在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → GDI绘制坐标系(画出了横坐标、纵坐标、网格线等等)

GDI绘制坐标系(画出了横坐标、纵坐标、网格线等等)

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:0.07M
  • 下载次数:82
  • 浏览次数:509
  • 发布时间:2019-10-21
  • 实例类别:C#语言基础
  • 发 布 人:BoBoGreatHaHa
  • 文件格式:.zip
  • 所需积分:1
 相关标签: GDI GD 坐标

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

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;
        }
    }
}

标签: GDI GD 坐标

实例下载地址

GDI绘制坐标系(画出了横坐标、纵坐标、网格线等等)

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警