实例介绍
【实例简介】
【实例截图】
【核心代码】
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GdiCoordinateSystem
{
public partial class MainForm : Form
{
private Bitmap m_Bmp;
private Graphics m_Graphics;
private float m_Scale = 0.0f; //放大倍数
private Point m_CanvasOrigin; //屏幕坐标原点
private float m_FillWidth = 2.1f; //绘制鼠标点时正方形的宽度
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
m_Bmp = new Bitmap(Pb_CoordinateSystem.Width, Pb_CoordinateSystem.Height);
m_Scale = 1f;
m_CanvasOrigin = new Point(Pb_CoordinateSystem.Width / 2, Pb_CoordinateSystem.Height / 2);
m_Graphics = Graphics.FromImage(m_Bmp);
DrawCoordinateSystem(new ArrayList(), new ArrayList(), new ArrayList());
Pb_CoordinateSystem.Image = m_Bmp;
}
/// <summary>
/// 绘制坐标系
/// </summary>
public void DrawCoordinateSystem(ArrayList ArrayListWRegionHistoryData, ArrayList ArrayListW2RegionHistoryData,
ArrayList ArrayListSRegionHistoryData)
{
m_Graphics.Clear(SystemColors.Control);//清除画笔,并填充背景面
DrawNoSafetyRegion(8000 * Math.Sqrt(2), Color.FromArgb(255, Color.Transparent));//安全区域标记
DrawRegionHistoryData(ArrayListWRegionHistoryData, ArrayListW2RegionHistoryData, ArrayListSRegionHistoryData); //先画区域再画坐标系,免得坐标系被覆盖
DrawNoSafetyRegion(50 * Math.Sqrt(2), SystemColors.Control);
//绘制网格线
float nIncrement = (50 * m_Scale); //网格间的间隔 根据比例绘制
int l_n32coordinatestr = 500;
if (m_Scale <= 0.7)
{
nIncrement = (50 * m_Scale); //网格间的间隔 根据比例绘制
}
else if (m_Scale > 0.7 && m_Scale <= 2)
{
nIncrement = (25 * m_Scale); //网格间的间隔 根据比例绘制
l_n32coordinatestr = 250;
}
else if (m_Scale > 2)
{
nIncrement = (float)(12.5 * m_Scale); //网格间的间隔 根据比例绘制
l_n32coordinatestr = 125;
}
//else
//{
// nIncrement = nIncrement;
//}
Font font = new System.Drawing.Font("Arial", 9, FontStyle.Regular);
Brush stringbrush = new SolidBrush(Color.FromArgb(255, Color.Blue));
//绘制竖向线
int l_n32lenx1 = (int)(Math.Abs(m_CanvasOrigin.X / nIncrement));
int l_n32lenx2 = (int)(Math.Abs((Pb_CoordinateSystem.Width - m_CanvasOrigin.X) / nIncrement));
string[] l_sArrayx1 = new string[l_n32lenx1 1];
string[] l_sArrayx2 = new string[l_n32lenx2 1];
for (int i = 0; i <= l_n32lenx1; i )
{
l_sArrayx1[i] = (-i * l_n32coordinatestr).ToString();
}
for (int i = 0; i <= l_n32lenx2; i )
{
l_sArrayx2[i] = (i * l_n32coordinatestr).ToString();
}
int jx1 = 0;
for (float x = m_CanvasOrigin.X; x >= 0; x -= nIncrement)
{
m_Graphics.DrawLine(Pens.Gray, x, 0, x, Pb_CoordinateSystem.Height);
if (jx1 <= l_n32lenx1 && jx1 % 2 == 0 && l_sArrayx1[jx1] != "0")
{
m_Graphics.DrawString(l_sArrayx1[jx1], font, stringbrush, x, m_CanvasOrigin.Y);
}
jx1 ;
}
int jx2 = 0;
for (float x = m_CanvasOrigin.X; x <= Pb_CoordinateSystem.Width; x = nIncrement)
{
m_Graphics.DrawLine(Pens.Gray, x, 0, x, Pb_CoordinateSystem.Height);
if (jx2 <= l_n32lenx2 && jx2 % 2 == 0 && l_sArrayx2[jx2] != "-0")
{
m_Graphics.DrawString(l_sArrayx2[jx2], font, stringbrush, x, m_CanvasOrigin.Y);
}
jx2 ;
}
//绘制横向线
int l_n32leny1 = (int)(Math.Abs(m_CanvasOrigin.Y / nIncrement));
int l_n32leny2 = (int)(Math.Abs((Pb_CoordinateSystem.Width - m_CanvasOrigin.Y) / nIncrement));
string[] l_sArrayy1 = new string[l_n32leny1 1];
string[] l_sArrayy2 = new string[l_n32leny2 1];
for (int i = 0; i <= l_n32leny1; i )
{
l_sArrayy1[i] = (i * l_n32coordinatestr).ToString();
}
for (int i = 0; i <= l_n32leny2; i )
{
l_sArrayy2[i] = (-i * l_n32coordinatestr).ToString();
}
int j = 0;
for (float y = m_CanvasOrigin.Y; y >= 0; y -= nIncrement)
{
m_Graphics.DrawLine(Pens.Gray, 0, y, Pb_CoordinateSystem.Width, y);
if (j <= l_n32leny1 && j % 2 == 0)
{
m_Graphics.DrawString(l_sArrayy1[j], font, Brushes.Blue, m_CanvasOrigin.X, y);
}
j ;
}
int j1 = 0;
for (float y = m_CanvasOrigin.Y; y <= Pb_CoordinateSystem.Width; y = nIncrement)
{
m_Graphics.DrawLine(Pens.Gray, 0, y, Pb_CoordinateSystem.Width, y);
if (j1 <= l_n32leny2 && j1 % 2 == 0 && l_sArrayy2[j1] != "-0")
{
m_Graphics.DrawString(l_sArrayy2[j1], font, Brushes.Blue, m_CanvasOrigin.X, y);
}
j1 ;
}
//坐标系
Pen p = new Pen(Color.Blue, 1);
m_Graphics.DrawLine(p, 0, m_CanvasOrigin.Y, Pb_CoordinateSystem.Width, m_CanvasOrigin.Y);
m_Graphics.DrawLine(p, m_CanvasOrigin.X, 0, m_CanvasOrigin.X, Pb_CoordinateSystem.Height);
p.Dispose();
}
/// <summary>
/// 绘制圆心不显示安全区域的部分
/// </summary>
/// <param name="radius"></param>
/// <param name="color"></param>
public void DrawNoSafetyRegion(double radius, Color color)
{
List<AngleAndRadius> aarList = new List<AngleAndRadius>();
aarList.Add(new AngleAndRadius(135, radius));
List<Point> pointList = PolarPointToScreenPoint(aarList);
int x0 = m_CanvasOrigin.X;
int y0 = m_CanvasOrigin.Y;
Point Screenpointx0y0 = PixelPointToScreenPoint(new Point(x0, y0)); //屏幕零点坐标
pointList.Add(Screenpointx0y0);
List<Point> listep = ScreenPointToPixelPoint(pointList); //像素点集合(作图时使用)
Graphics tempgra = Graphics.FromImage(m_Bmp);
tempgra.CompositingMode = CompositingMode.SourceCopy; //保证重合区域不显示为多层颜色
tempgra.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
tempgra.PixelOffsetMode = PixelOffsetMode.HighQuality;
tempgra.SmoothingMode = SmoothingMode.AntiAlias;
Brush brush = new SolidBrush(color);
GraphicsPath gpp = new GraphicsPath();
int height = Math.Abs(listep[0].X - listep[1].X) * 2;
gpp.AddPie(listep[0].X, listep[0].Y, height, height, 135, 270);
tempgra.FillPath(brush, gpp);
}
/// <summary>
/// 将Polar点(距离角度)转换为屏幕点(直角坐标系点)
/// </summary>
/// <param name="aarList"></param>
/// <returns></returns>
public List<Point> PolarPointToScreenPoint(List<AngleAndRadius> aarList)
{
List<Point> pointList = new List<Point>();
for (int i = 0; i < aarList.Count; i )
{
double radius = aarList[i].radius;
double angle = aarList[i].angle / 180 * Math.PI;
double x = radius * Math.Cos(angle);
double y = radius * Math.Sin(angle);
pointList.Add(new Point((int)x, (int)y));
}
return pointList;
}
/// <summary>
/// 像素点转屏幕坐标
/// </summary>
/// <param name="ePoint"></param>
/// <returns></returns>
public Point PixelPointToScreenPoint(Point ePoint)
{
Point sPoint = new Point();
SizeF ef = (Size)m_CanvasOrigin;
sPoint.X = (int)((ePoint.X - ef.Width) * 10 / m_Scale); //屏幕点转换为坐标点的方法
sPoint.Y = (int)((ePoint.Y - ef.Height) * (-10) / m_Scale);
return sPoint;
}
/// <summary>
/// 屏幕坐标转像素点坐标
/// </summary>
/// <param name="listsp"></param>
/// <returns></returns>
public List<Point> ScreenPointToPixelPoint(List<Point> listsp)
{
List<Point> listep = new List<Point>();
int len = listsp.Count;
for (int i = 0; i < len; i )
{
listep.Add(ScreenPointToPixelPoint(listsp[i]));
}
return listep;
}
/// <summary>
/// 一组点的转换:
/// sPoint: 屏幕点的集合,将一组点放入List<Point>类中,sp:ScreenPoint
/// listep: 像素点的集合,将一组点放入List<Point>类中,ep:ePoint
/// </summary>
/// <param name="sPoint"></param>
/// <returns></returns>
public Point ScreenPointToPixelPoint(Point sPoint)
{
Point ePoint = new Point();
SizeF ef = (Size)m_CanvasOrigin;
ePoint.X = (int)(sPoint.X / 10 * m_Scale ef.Width); //屏幕点转换为坐标点的方法
ePoint.Y = (int)(sPoint.Y / (-10) * m_Scale ef.Height);
return ePoint;
}
private void DrawRegionHistoryData(ArrayList ArrayListWRegionHistoryData, ArrayList ArrayListW2RegionHistoryData,
ArrayList ArrayListSRegionHistoryData)
{
if (ArrayListW2RegionHistoryData.Count > 0)
{
RedrawRegionData(ArrayListW2RegionHistoryData, 3); //历史数据区域
//RedrawRegionPoint(ArrayListWPointHistoryData,1); //历史数据点
}
if (ArrayListWRegionHistoryData.Count > 0)
{
RedrawRegionData(ArrayListWRegionHistoryData, 1); //历史数据区域
//RedrawRegionPoint(ArrayListWPointHistoryData,1); //历史数据点
}
if (ArrayListSRegionHistoryData.Count > 0)
{
RedrawRegionData(ArrayListSRegionHistoryData, 2); //历史数据区域
// RedrawRegionPoint(ArrayListSPointHistoryData, 2); //历史数据点
}
}
/// <summary>
/// 重新绘制区域曲线 RedrawRegionData()
/// </summary>
/// <param name="ArrayListRegionHistoryData"></param>
/// <param name="color"></param>
public void RedrawRegionData(ArrayList ArrayListRegionHistoryData, int color)
{
int count = ArrayListRegionHistoryData.Count;
List<Point> l_listsp = new List<Point>();
List<AngleAndRadius> l_listPolar = new List<AngleAndRadius>();
for (int i = 0; i < count; i )
{
l_listsp.AddRange((List<Point>)(ArrayListRegionHistoryData[i]));
l_listPolar = (ScreenPointListToPolarPointList(l_listsp));
List<AngleAndRadius> l_lNoDele = new List<AngleAndRadius>();
List<AngleAndRadius> l_lDele = new List<AngleAndRadius>();
SelectNoDeleteAngle(l_listPolar, out l_lDele, out l_lNoDele);
DeleteSameAngleSmallerRadius(l_lDele, 0);
l_listPolar.Clear();
l_listPolar.AddRange(l_lDele);
l_listPolar.AddRange(l_lNoDele);
l_listPolar = DeleteSelectedAngle(225.0, 315.0, l_listPolar); //删除指定角度的数据
SortPointListAsAngle(l_listPolar);
l_listsp.Clear();
l_listsp = PolarPointToScreenPoint(l_listPolar);
Point Screenpointx0y0 = PixelPointToScreenPoint(new Point(m_CanvasOrigin.X, m_CanvasOrigin.Y)); //屏幕零点坐标
l_listsp.Add(Screenpointx0y0);
if (l_listsp.Count > 0)
{
DrawOutlineRegion(l_listsp, color);
l_listsp.Clear();
}
}
}
/// <summary>
/// 将一组屏幕点转换为极坐标点
/// listsp: 屏幕点的集合
/// ListAngleAndRadius:极坐标点的集合
/// </summary>
/// <param name="listsp"></param>
/// <returns ListAngleAndRadius></returns>
public List<AngleAndRadius> ScreenPointListToPolarPointList(List<Point> listsp)
{
List<AngleAndRadius> ListAngleAndRadius = new List<AngleAndRadius>();
int listcout = listsp.Count;
for (int i = 0; i < listcout; i )
{
double Radius = PointToRadius(listsp[i]);
double Angle = PointToAngle(listsp[i]);
ListAngleAndRadius.Add(new AngleAndRadius(Angle, Radius));
}
return ListAngleAndRadius;
}
/// <summary>
/// 求点的Polar坐标长度
/// sPoint: 屏幕点坐标
/// </summary>
/// <param name="sPoint"></param>
/// <returns PointRadius ></returns>
public double PointToRadius(Point sPoint)
{
double length = Math.Pow(sPoint.X, 2) Math.Pow(sPoint.Y, 2);
double PointRadius = Math.Sqrt(length);
return PointRadius;
}
/// <summary>
/// 求点的极坐标角度
/// sPoint: 屏幕点坐标
/// </summary>
/// <param name="sPoint"></param>
/// <returns></returns>
public double PointToAngle(Point sPoint)
{
int px = sPoint.X;
int py = sPoint.Y;
double PointAngle = 0;
if (Math.Abs(px) > 0 && Math.Abs(py) > 0)
{
double PointRatio = (double)Math.Abs(py) / (double)Math.Abs(px);
PointAngle = Math.Atan(PointRatio) / Math.PI * 180;
if (px < 0 && py > 0)
{
PointAngle = 180 - PointAngle;
}
else if (px < 0 && py < 0)
{
PointAngle = 180;
}
else if (px > 0 && py < 0)
{
PointAngle = 360 - PointAngle;
}
}
else
{
if (px > 0 && py == 0)
{
PointAngle = 0;
}
else if (px == 0 && py > 0)
{
PointAngle = 90;
}
else if (px < 0 && py == 0)
{
PointAngle = 180;
}
else if (px == 0 && py < 0)
{
PointAngle = 270;
}
}
return PointAngle;
}
public void SelectNoDeleteAngle(List<AngleAndRadius> p_loriginaldata, out List<AngleAndRadius> p_lDeleteData, out List<AngleAndRadius> p_lNoDeleteData)
{
int l_n32count = p_loriginaldata.Count;
List<AngleAndRadius> l_lDeleteData = new List<AngleAndRadius>(); //可以按角度整数值进行删除的数据
List<AngleAndRadius> l_lNoDeleteData = new List<AngleAndRadius>(); //0-1度 和359-360的点
for (int j = 0; j < l_n32count; j )
{
if ((p_loriginaldata[j].angle >= 0 && p_loriginaldata[j].angle <= 1) ||
(p_loriginaldata[j].angle >= 359 && p_loriginaldata[j].angle <= 360))
{
l_lNoDeleteData.Add(p_loriginaldata[j]);
}
else
{
l_lDeleteData.Add(p_loriginaldata[j]);
}
}
p_lNoDeleteData = l_lNoDeleteData;
p_lDeleteData = l_lDeleteData;
}
/// <summary>
/// 删除集合中角度相同半径较小的元素
/// </summary>
/// <param name="list"></param>
/// <param name="digits"></param>
/// <returns></returns>
public List<AngleAndRadius> DeleteSameAngleSmallerRadius(List<AngleAndRadius> list, int digits)
{
for (int i = 0; i < list.Count - 1; i )
{
for (int j = 0; j < list.Count; j )
{
if (Math.Round(list[i].angle, digits) == Math.Round(list[j].angle, digits))
{
if (i != j)
{
if (list[i].radius <= list[j].radius)
{
var temp = list[i];
list[i] = list[j];
list[j] = temp;
}
list.RemoveAt(j);
j--;
}
}
}
}
return list;
}
/// <summary>
/// 删除指定角度的距离
/// </summary>
/// <param name="p_staang"></param>
/// <param name="p_endang"></param>
/// <param name="p_ARList"></param>
/// <returns></returns>
public List<AngleAndRadius> DeleteSelectedAngle(double p_staang, double p_endang, List<AngleAndRadius> p_ARList)
{
for (int j = 0; j < 2; j )
{
for (int i = 0; i < p_ARList.Count; i )
{
if (p_ARList[i].angle > p_staang && p_ARList[i].angle < p_endang)
{
p_ARList.RemoveAt(i);
i = 0;
}
}
}
return p_ARList;
}
/// <summary>
/// 冒泡法排序(分别按polar图的角度和半径进行排序)
/// </summary>
/// <param name="listpp"></param>
/// <returns></returns>
public List<AngleAndRadius> SortPointListAsAngle(List<AngleAndRadius> listpp) //按角度由小到大排序
{
var temp = listpp[0];
for (int i = 0; i < listpp.Count - 1; i ) //冒泡法排序(小到大)
{
for (int j = 0; j < listpp.Count - 1 - i; j )
{
if (listpp[j].angle > listpp[j 1].angle)
{
temp = listpp[j];
listpp[j] = listpp[j 1];
listpp[j 1] = temp;
}
}
}
return listpp;
}
/// <summary>
/// 绘制阴影
/// </summary>
/// <param name="listsp"></param>
/// <param name="color"></param>
public void DrawOutlineRegion(List<Point> listsp, int color)
{
Brush brush;
Graphics tempgra = Graphics.FromImage(m_Bmp);
tempgra.CompositingMode = CompositingMode.SourceCopy; //保证重合区域不显示为多层颜色
//tempgra.SmoothingMode = SmoothingMode.HighQuality; //添加该句会导致重合部分有轮廓印迹
tempgra.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
tempgra.PixelOffsetMode = PixelOffsetMode.HighQuality;
List<Point> listep = ScreenPointToPixelPoint(listsp);//像素点集合(作图时使用)
GraphicsPath gpp = new GraphicsPath();
//gpp.AddClosedCurve(listep.ToArray(), 0);
gpp.AddCurve(listep.ToArray(), 0);
switch (color)
{
case 1:
brush = new SolidBrush(Color.FromArgb(100, Color.Orange));
tempgra.FillPath(brush, gpp);
//tempgra.FillClosedCurve(brush, listep.ToArray(), FillMode.Winding, 0.5f);
break;
case 2:
brush = new SolidBrush(Color.FromArgb(100, Color.Red));
//brush = new HatchBrush(HatchStyle.NarrowHorizontal,Color .Transparent, Color.FromArgb(80, Color.Red));
tempgra.FillPath(brush, gpp);
break;
case 3:
brush = new SolidBrush(Color.FromArgb(100, Color.Yellow));
//graphics.FillPath(brush, gpp);
tempgra.FillPath(brush, gpp);
break;
default:
break;
}
tempgra.Dispose();
}
}
public class AngleAndRadius
{
public double angle;
public double radius;
public AngleAndRadius(double angle, double radius)
{
this.angle = angle;
this.radius = radius;
}
}
}
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论