实例介绍
【实例简介】
【实例截图】
【核心代码】
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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论