三点画弧(呵呵,这是我自己写的,请大家指正)

(公司现做项目,为了大家交流学习--我在网站上百度了好久都木有找到代码)

三点画弧类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Xml;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.ComponentModel;

namespace Fixpro3._1
{
    /// <summary>
    /// 三点确定圆弧
    /// </summary>
    class CssArc : CsElement
    {
        #region 属性


        private Point bnPoint;
        private PointF _bnPoint;
        /// <summary>
        /// 起点
        /// </summary>
        [Description("起点坐标"), Category("私有属性"), ReadOnly(true)]
        public Point BnPoint
        {
            get
            {
                return bnPoint;
            }
            set
            {
                bnPoint = value;
                _bnPoint = new PointF((int)(value.X / 10000f * 25.4f), (int)(value.Y / 10000f * 25.4f));
           
            }
        }

        private Point mdPoint;
        private PointF _mdPoint;
        /// <summary>
        /// 中点
        /// </summary>
        [Description("中点坐标"), Category("私有属性"), ReadOnly(true) ,Browsable(false)]
        public Point MdPoint
        {
            get
            {
                return mdPoint;
            }
            set
            {
                mdPoint = value;
                _mdPoint = new PointF((int)(value.X / 10000f * 25.4f), (int)(value.Y / 10000f * 25.4f));
            }
        }

        private Point edPoint;
        private PointF _edPoint;
        /// <summary>
        /// 端点
        /// </summary>
        [Description("终点坐标"), Category("私有属性"), ReadOnly(true)]
        public Point EdPoint
        {
            get
            {
                return edPoint;
            }
            set
            {
                edPoint = value;
                _edPoint = new PointF((int)(value.X / 10000f * 25.4f), (int)(value.Y / 10000f * 25.4f));
           
            }
        }

        private float r;
        /// <summary>
        /// 半径
        /// </summary>
        [Description("半径坐标"), Category("私有属性")]
        public float R
        {
            get
            {
                return r;
            }
            set
            {
                r = value;
            }
        }

        private float _bnAngle;
        /// <summary>
        /// 起点角度(相对X轴逆时针,是以圆心为原点的坐标系)
        /// </summary>
        [Description("起点角度(相对圆心为原点的坐标系)"), Category("私有属性")]
        public float BnAngle
        {
            get
            {
                return _bnAngle;
            }
            set
            {
                _bnAngle = value;
            }
        }

        private float _mdAngle;
        /// <summary>
        /// 中点角度
        /// </summary>
        [Browsable(false)]
        public float MdAngle
        {
            get
            {
                return _mdAngle;
            }
            set
            {
                _mdAngle = value;
            }
        }

        private float _edAngle;
        /// <summary>
        /// 端点角度(相对X轴逆时针,是以圆心为原点的坐标系)
        /// </summary>
        [Description("终点角度(相对圆心为原点的坐标系)"), Category("私有属性")]
        public float EdAngle
        {
            get
            {
                return _edAngle;
            }
            set
            {
              
                _edAngle = value;
            }
        }

        private float _roundAngle;
        /// <summary>
        /// 圆弧角度
        /// </summary>
        [Description("终点角度(相对圆心为原点的坐标系)"), Category("私有属性"), ReadOnly(true)]
        public float RoundAngle
        {
            get
            {
                return _roundAngle;
            }
            set
            {
                _roundAngle = value;
            }
        }

        private int arcLength;
        private float _arcLength;
        /// <summary>
        /// 弧长
        /// </summary>
        [Description("弧长"), Category("私有属性"), ReadOnly(true)]
        public int ArcLength
        {
            get
            {
                return arcLength;
            }
            set
            {
                arcLength = value;
                _arcLength = (value / 10000f * 25.4f);
            }
        }

        private EmCut _mill;
        /// <summary>
        /// 铣的方式
        /// </summary>
        [Description("铣的方式(铣圆弧:In(内铣)、Out(外铣)、Middle(中间铣)"), Category("铣的方式")]
        public EmCut Mill
        {
            get
            {
                return _mill;
            }
            set
            {
                _mill = value;
            }
        }
        #endregion

        #region 构造函数


        /// <summary>
        /// 无参构造函数

 

        /// </summary>
        public CssArc()
        {
            name = "Arc";
        }
        /// <summary>
        /// 有参构造函数(毫米)

        /// </summary>
        /// <param name="center">圆心</param>
        /// <param name="depth">深度</param>
        /// <param name="color">颜色</param>
        /// <param name="way">钻铣方式</param>
        /// <param name="mill">铣的方式</param>
        /// <param name="bnPoint">起点</param>
        /// <param name="mdPoint">中点</param>
        /// <param name="edPoint">端点</param>
        /// <param name="bnAngle">起点角度</param>
        /// <param name="edAngle">端的角度</param>
        /// <param name="ttAngle">总角度</param>
        /// <param name="r">半径</param>
        /// <param name="arcLength">弧长</param>
        /// <param name="width">弧宽</param>
        public CssArc(PointF center, float depth, Color color, EmWay way, EmCut mill, PointF bnPoint, PointF mdPoint, PointF edPoint, float bnAngle,float mdAngle, float edAngle, float swAngle, float _r, float arcLength)
            : base(center, depth, color, way)
        {
            name = "Arc";
            this._bnPoint = bnPoint;
            this._mdPoint = mdPoint;
            this._edPoint = edPoint;
            this.BnAngle = bnAngle;
            this.MdAngle = mdAngle;
            this.EdAngle = edAngle;
            this.RoundAngle = swAngle;
            this._arcLength = arcLength;
            this.R = _r;
            this.Mill = mill;
        }
        /// <summary>
        /// 有参构造函数(英寸)
        /// </summary>
        /// <param name="center">圆心</param>
        /// <param name="depth">深度</param>
        /// <param name="color">颜色</param>
        /// <param name="way">钻铣方式</param>
        /// <param name="mill">铣的方式</param>
        /// <param name="bnPoint">起点</param>
        /// <param name="mdPoint">中点</param>
        /// <param name="edPoint">端点</param>
        /// <param name="bnAngle">起点角度</param>
        /// <param name="edAngle">端的角度</param>
        /// <param name="swAngle">总角度</param>
        /// <param name="r">半径</param>
        /// <param name="arcLength">弧长</param>
        public CssArc(Point center, int depth, Color color, EmWay way, EmCut mill, Point _bnPoint, Point _mdPoint, Point _edPoint, float bnAngle, float mdAngle, float edAngle, float swAngle, float _r, int _arcLength)
            : base(center, depth, color, way)
        {
            name = "Arc";
            this.BnPoint = _bnPoint;
            this.MdPoint = _mdPoint;
            this.EdPoint = _edPoint;
            this.BnAngle = bnAngle;
            this.MdAngle = mdAngle;
            this.EdAngle = edAngle;
            this.RoundAngle = swAngle;
            this.ArcLength = _arcLength;
            this.R = _r;
            this.Mill = mill;
        }
        #endregion

        #region 方法
        /// <summary>
        /// 圆弧动态绘制效果

        /// </summary>
        /// <param name="ptb">画布</param>
        /// <param name="Arc">圆弧属性</param>
        /// <param name="Move">移动的点</param>
        /// <param name="offset">偏移量</param>
        /// <param name="scale">缩放比例</param>
        /// <param name="morX">X镜像</param>
        /// <param name="morY">Y镜像</param>
        public static void Arcdynamic(PictureBox ptb, CssArc Arc, Point Move, Point offset, float scale, bool morX, bool morY)
        {
            ptb.Refresh();
            Graphics g = Graphics.FromHwnd(ptb.Handle);
            g.TranslateTransform(ptb.Width / 2f / 96f * 10000f / scale + offset.Y, ptb.Height / 2f / 96f * 10000f / scale + offset.X);
            g.PageUnit = GraphicsUnit.Inch;
            g.PageScale = scale / 10000f;
            Pen pn = new Pen(Color.LimeGreen, 0.05f);
            pn.DashStyle = DashStyle.Dash;//线段的可视效果


            #region 变量
            CssArc arc=new CssArc();
            Point bn = Arc.BnPoint;
            Point md = Arc.MdPoint;
            float slopeBm, slopeMe, slopeMc, slopeNc;//斜率
            float k1, k2;//斜率

            Point M = new Point();
            Point N = new Point();
            Point Cen = new Point();
            int r = 0;
            float bnA, edA, roundA;
            #endregion

            if (frmMain.two==false)
            {
                g.DrawLine(pn, bn.Y, bn.X, Move.Y, Move.X);
            }
            if (frmMain.two==true)
            {
                try
                {
                    #region 数据计算
                    k1 = arc.Slope(bn, md);
                    k2 = arc.Slope(md, Move);

                    if (k1 == k2)
                    {
                        //判断三点是否在一天直线上
                        return;
                    }
                    else
                    {
                        //起点与中点连接成的直线的斜率
                        slopeBm = arc.Slope(bn, md);
                        //中点与端点连接成直线的斜率

 

                        slopeMe = arc.Slope(md, Move);
                        //求中垂线的坐标值


                        M.X = (bn.X + md.X) / 2;
                        M.Y = (bn.Y + md.Y) / 2;
                        N.X = (md.X + Move.X) / 2;
                        N.Y = (md.Y + Move.Y) / 2;
                        //中垂线的斜率
                        slopeMc = -1 / slopeBm;
                        slopeNc = -1 / slopeMe;
                        #region 点斜式方程组
                        //arc.center.Y - M.Y = (int)slopeMc * (arc.center.X - M.X);
                        //arc.center.Y - N.Y = (int)slopeNc * (arc.center.X - N.X);
                        #endregion
                        //计算中心坐标
                        Cen.X = Convert.ToInt32(((N.Y - M.Y) - (slopeNc * N.X - slopeMc * M.X)) / (slopeMc - slopeNc));
                        Cen.Y = Convert.ToInt32(slopeNc * (((N.Y - M.Y) - (slopeNc * N.X - slopeMc * M.X)) / (slopeMc - slopeNc) - N.X) + N.Y);
                        //计算半径
                        r = (int)Math.Sqrt(Math.Pow(Cen.X - bn.X, 2) + Math.Pow(Cen.Y - bn.Y, 2));
                    }
                    //计算角度
                    bnA = arc.PAngle(bn, Cen);
                    edA = arc.PAngle(Move, Cen);
                    roundA = arc.PAngle(bnA, edA, bn, md, Move, Cen);
                    //
                    float startA = arc.PAngle(bnA, edA, md, Cen);
                    int d = r * 2;
                    int x = Cen.X - r;
                    int y = Cen.Y - r;
                    #endregion

                    g.DrawArc(pn, y, x, d, d, startA, roundA);
                }
                catch
                { }
                g.Dispose();
            }
        }
        /// <summary>
        /// 根据角度推出点坐标

        /// </summary>
        /// <param name="angle">角度</param>
        /// <param name="center">中心点坐标</param>
        /// <param name="_r">半径</param>
        /// <returns>点坐标</returns>
        public Point Npoint(float angle,Point center,float _r)
        {
            PointF cen = new PointF();
            cen.X = (float)center.X;
            cen.Y = (float)center.Y;
          
            //半径
            float r = _r * 10000f / 25.4f;

            //将角度化为弧度

            double radian = angle * Math.PI / 180;

            #region 参照公式
            //弧度
            //double v = Math.PI / 180;
            //正弦函数
            //s = (bn.Y - cen.Y) / R;
            //余弦函数
            //cx = (bn.X - cen.X) / R;
            #endregion

            float sy = (float)Math.Sin(radian);
            float cx = (float)Math.Cos(radian);
           
            int x = (int)(cx * r + cen.X);
            int y = (int)(sy * r + cen.Y);
     

            Point pt = new Point(x, y);

            return pt;
        }
        /// <summary>
        /// 计算点的斜率
        /// </summary>
        /// <param name="pt1">选定的原点</param>
        /// <param name="pt2">要求斜率的点</param>
        /// <returns>斜率</returns>
        public float Slope(Point pt1, Point pt2)
        {
            return (float)(pt2.Y - pt1.Y) / (float)(pt2.X - pt1.X);
        }
        /// <summary>
        /// 计算点的角度
        /// </summary>
        /// <param name="point">要计算的点的坐标</param>
        /// <param name="centers">圆心点坐标</param>
        /// <returns>角度</returns>
        public float PAngle(Point point, Point centers)
        {
            PointF pt = new PointF();
            //中心点


            PointF cen = new PointF();
            //斜率
            float k;

            pt.X = (float)point.X;
            pt.Y = (float)point.Y;
            cen.X = (float)centers.X;
            cen.Y = (float)centers.Y;

            //斜率
            k = (pt.Y - cen.Y) / (pt.X - cen.X);

            //弧度
            double radian;
            //角度
            double RAngle = 0;
            //弧度与角度的转换
            double v = 180.0 / Math.PI;

            radian = Math.Atan(k);

            //区分第一、三象限
            if (radian >= 0)
            {
                if (pt.X > cen.X)
                {
                    //一
                    RAngle = radian * v;
                }
                else if (pt.X < cen.X)
                {
                    //三


                    RAngle = 180.0 + radian * v;
                }
            }
            else
            {
                //区分第二、四象限
                radian = Math.Abs(radian);

                if (pt.X > cen.X)
                {
                    //四


                    RAngle = 360.0 - radian * v;
                }
                else if (pt.X < cen.X)
                {
                    //二


                    RAngle = 180.0 - radian * v;
                }
            }

            return (float)RAngle;
        }
        /// <summary>
        /// 判断角的逆反(用于选中圆弧)
        /// </summary>
        /// <param name="angle1">第一个点的角度</param>
        /// <param name="pt">第二个点的坐标</param>
        /// <param name="angle3">第三个点的角度</param>
        /// <param name="angle0">要对比的角度</param>
        /// <returns>bool值</returns>
        public bool PAngle(float angle1, Point pt, float angle3, float angle0)
        {
            //第三个点的角度


            float ed = angle3;
            //第二个点的角度


            float angle2 = PAngle(pt, center);
            /****使三个点的角度依次增大******/
            while (angle2 < angle1)
            {
                //判断第二个点的角度是否小于第一个点的角度,小于就给第二个点的角度加360,直到条件为假


                angle2 += 360;
            }
            while (angle3 < angle2)
            {
                //判断第三个点的角度是否小于第二个点的角度,小于就给第三个点的角度加360,直到条件为假


                angle3 += 360;
            }
            //如果第三个点的角度减去第一个点的角度大于360,则三个点是顺时针方向排布,反之,则逆时针方向排布


            if ((angle3 - angle1) > 360)
            {
                //顺时针排布


                if ((360 - angle0) > (360 - angle1) && (360 - angle0) < angle3)
                {
                    return true;
                }
                return false;
            }
            else
            {
                //逆时针排布


                if ((360 - angle0) < (360 - angle1) && (360 - angle0) > (360 - angle3))
                {
                    return true;
                }
                return false;
            }
        }
        /// <summary>
        /// 圆心角角度(判断角度的逆反,如果是逆的,则互换起点和终点的相关信息)
        /// </summary>
        /// <param name="bn">第一个点的角度</param>
        /// <param name="ed">终点的角度</param>
        /// <param name="bnp">起始点坐标</param>
        /// <param name="mdp">中点坐标</param>
        /// <param name="edp">终点坐标</param>
        /// <param name="cen">中心点坐标</param>
        /// <returns>圆心角角度</returns>
        public float PAngle(float bn, float ed, Point bnp, Point mdp, Point edp, Point cen)
        {
            float angle;
            if (bn == ed)
            {
                angle = 360;
            }
            else
            {
                float mdAngle = PAngle(mdp, cen);
                float edangle = ed;
                while (mdAngle < bn)
                {
                    //判断第二个点的角度是否小于第一个点的角度,小于就给第二个点的角度加360,直到条件为假,跳出循环
                    mdAngle = mdAngle + 360;
                }
                while (edangle < mdAngle)
                {
                    //判断第三个点的角度是否小于第二个点的角度,小于就给第三个点的角度加360,直到条件为假,跳出循环
                    edangle = edangle + 360;
                }
                //如果第三个点的角度减去第一个点的角度大于360,则三个点是顺时针方向排布,反之,则逆时针方向排布

 

                if (edangle - bn > 360)
                {
                    //顺时针排布

 

                    if (bn > ed)
                    {
                        //angle = 360 - (EdAngle + 360 - BnAngle);
                        angle = bn - ed;
                    }
                    else
                    {
                        angle = 360 - (ed - bn);

                    }
                }
                else
                {
                    //逆时针排布

 

                    if (bn < ed)
                    {
                        angle = ed - bn;
                    }
                    else
                    {
                        angle = 360 - (bn - ed);
                    }
                }
            }
            return angle;
        }
        /// <summary>
        /// 圆心角角度(判断角度的逆反,如果是逆的,则互换起点和终点的相关信息)
        /// </summary>
        /// <param name="arc">圆弧属性</param>
        /// <returns>圆弧属性</returns>
        public CssArc PAngle(CssArc arc)
        {
            float angle;

            arc.MdAngle = PAngle(arc.MdPoint, arc.Center);

            if (arc.BnAngle == arc.EdAngle)
            {
                angle = 360;
            }
            else
            {
                float mdAngle = arc.MdAngle;
                float edangle = arc.EdAngle;
                while (mdAngle < arc.BnAngle)
                {
                    //判断第二个点的角度是否小于第一个点的角度,小于就给第二个点的角度加360,直到条件为假,跳出循环
                    mdAngle = mdAngle + 360;
                }
                while (edangle < mdAngle)
                {
                    //判断第三个点的角度是否小于第二个点的角度,小于就给第三个点的角度加360,直到条件为假,跳出循环
                    edangle = edangle + 360;
                }
                //如果第三个点的角度减去第一个点的角度大于360,则三个点是顺时针方向排布,反之,则逆时针方向排布

 

                if (edangle - arc.BnAngle > 360)
                {
                    //顺时针排布

 

                    if (arc.BnAngle > arc.EdAngle)
                    {
                        angle = arc.BnAngle - arc.EdAngle;
                    }
                    else
                    {
                        angle = 360 - (arc.EdAngle - arc.BnAngle);

                    }
                }
                else
                {
                    //逆时针排布

 

                    if (arc.BnAngle < arc.EdAngle)
                    {
                        angle = arc.EdAngle - arc.BnAngle;
                    }
                    else
                    {
                        angle = 360 - (arc.BnAngle - arc.EdAngle);
                    }
                    //交换起点和终点的坐标
                    float temp = arc.BnAngle;
                    arc.BnAngle = arc.EdAngle;
                    arc.EdAngle = temp;
                    Point tp = arc.BnPoint;
                    arc.BnPoint = arc.EdPoint;
                    arc.EdPoint = tp;
                }
            }
            arc.RoundAngle = angle;
            return arc;
        }
        /// <summary>
        /// 判断起点角度
        /// </summary>
        /// <param name="bn">第一个点的角度</param>
        /// <param name="ed">终点的角度</param>
        /// <param name="md">中点坐标</param>
        /// <param name="cen">中心点坐标</param>
        /// <returns>起点角度</returns>
        public float PAngle(float bn, float ed, Point md, Point cen)
        {
            float mdAngle = PAngle(md, cen);
            float edangle = ed;
            while (mdAngle < bn)
            {
                mdAngle = mdAngle + 360;
            }
            while (edangle < mdAngle)
            {
                edangle = edangle + 360;
            }
            float startAngle;

            if (edangle - bn > 360)
            {
                //鼠标点下的顺序是顺时针的。

                startAngle = -bn + 90;
            }
            else
            {
                //鼠标点下的顺序是逆时针的。

                startAngle = -ed + 90;
            }
            return startAngle;
        }
        /// <summary>
        /// 获取圆弧的属性数据

        /// </summary>
        /// <param name="arc">圆弧属性</param>
        public void GetArcData(CssArc arc)
        {
            float slopeBm, slopeMe, slopeMc, slopeNc;//斜率
            float k1, k2;//斜率
            Point M = new Point();
            Point N = new Point();

            k1 = Slope(arc.BnPoint, arc.MdPoint);
            k2 = Slope(arc.MdPoint, arc.EdPoint);
            try
            {
                if (k1 == k2)
                {
                    //判断三点是否在一天直线上
                    return;
                }
                else
                {
                    //起点与中点连接成的直线的斜率
                    slopeBm = Slope(arc.BnPoint, arc.MdPoint);
                    //中点与端点连接成直线的斜率

                    slopeMe = Slope(arc.MdPoint, arc.EdPoint);
                    //求中垂线的坐标值

                    M.X = (arc.BnPoint.X + arc.MdPoint.X) / 2;
                    M.Y = (arc.BnPoint.Y + arc.MdPoint.Y) / 2;
                    N.X = (arc.MdPoint.X + arc.EdPoint.X) / 2;
                    N.Y = (arc.MdPoint.Y + arc.EdPoint.Y) / 2;
                    //中垂线的斜率
                    slopeMc = -1 / slopeBm;
                    slopeNc = -1 / slopeMe;
                    #region 点斜式方程组
                    //arc.center.Y - M.Y = (int)slopeMc * (arc.center.X - M.X);
                    //arc.center.Y - N.Y = (int)slopeNc * (arc.center.X - N.X);
                    #endregion
                    //计算中心坐标
                    arc.center.X = Convert.ToInt32(((N.Y - M.Y) - (slopeNc * N.X - slopeMc * M.X)) / (slopeMc - slopeNc));
                    arc.center.Y = Convert.ToInt32(slopeNc * (((N.Y - M.Y) - (slopeNc * N.X - slopeMc * M.X)) / (slopeMc - slopeNc) - N.X) + N.Y);
                    //计算半径
                    arc.R = (float)(Math.Sqrt(Math.Pow(arc.Center.X - arc.BnPoint.X, 2) + Math.Pow(arc.Center.Y - arc.BnPoint.Y, 2)) * 25.4f / 10000f);
                }
                arc.BnAngle = PAngle(arc.BnPoint, arc.Center);

                arc.EdAngle = PAngle(arc.EdPoint, arc.Center);
                arc = PAngle(arc);
                arc.ArcLength = (int)(arc.RoundAngle * (Math.PI / 180) * R);
                //添加到元素集合

                CsCommunal.SetElements.Add(arc);
            }
            catch
            {

            }

        }
        /// <summary>
        /// 三点画弧正交镜像后的坐标
        /// </summary>
        /// <param name="morX">X轴镜像</param>
        /// <param name="morY">Y轴镜像</param>
        /// <param name="sceX">X轴镜像</param>
        /// <param name="sceY">Y轴镜像</param>
        /// <param name="pt1">要偏移的点的坐标</param>
        /// <param name="facePoint">偏移向量</param>
        /// <returns>偏移后的点的坐标</returns>
        public Point GetNewPoint(bool morX, bool morY, bool sceX, bool sceY, Point pt1, params Point[] facePoint)
        {
            int x, y;
            if (sceX)
            {
                x = pt1.X * (-1);
            }
            else
            {
                x = pt1.X;
            }
            if (sceY)
            {
                y = pt1.Y * (-1);
            }
            else
            {
                y = pt1.Y;
            }
            Point pt0 = new Point(x, y);
            if (facePoint != null)
            {
                foreach (Point pt in facePoint)
                {
                    if (pt.X != 0)
                    {
                        pt0.Y += pt.Y;
                        pt0.X += pt.X - (pt0.X - Center.X) * 2;
                    }
                    if (pt.Y != 0)
                    {
                        pt0.Y += pt.Y - (pt0.Y - Center.Y) * 2;
                        pt0.X += pt.X;
                    }
                }
            }
            if (morX)
            {
                pt0.Y = pt0.Y * (-1);
            }
            if (morY)
            {
                pt0.X = pt0.X * (-1);
            }
            return pt0;
        }
        /// <summary>
        /// 三点画弧正交镜像后的坐标
        /// </summary>
        /// <param name="morX">X轴镜像</param>
        /// <param name="morY">Y轴镜像</param>
        /// <param name="pt1">要偏移的点的坐标</param>
        /// <param name="facePoint">偏移向量</param>
        /// <returns>偏移后的点的坐标</returns>
        public Point GetNewPoint(bool morX, bool morY, Point pt1, params Point[] facePoint)
        {
            Point pt0 = pt1;

            if (facePoint != null)
            {
                foreach (Point pt in facePoint)
                {
                    if (pt.X != 0)
                    {
                        pt0.Y += pt.Y;
                        pt0.X += pt.X - (pt0.X - Center.X) * 2;
                    }
                    if (pt.Y != 0)
                    {
                        pt0.Y += pt.Y - (pt0.Y - Center.Y) * 2;
                        pt0.X += pt.X;
                    }
                }
            }
            if (morX)
            {
                pt0.Y = pt0.Y * (-1);
            }
            if (morY)
            {
                pt0.X = pt0.X * (-1);
            }
            return pt0;
        }
        /// <summary>
        /// 匹配刀号


        /// </summary>
        /// <param name="txxs">刀数据集合</param>
        /// <param name="r">圆弧半径</param>
        /// <returns>刀号</returns>
        public StTXX GetTxx(List<StTXX> txxs, float r)
        {
            StTXX txx = new StTXX();
            StTXX txx1 = new StTXX();
            StTXX txx2 = new StTXX();

            if (txxs != null)
            {
                //集合中数据不为空,则开始匹配刀号


                for (int i = 0; i < txxs.Count; i++)
                {
                    if (CsOthers.IsEqual(txxs[i].TD, 3.0f))
                    {
                        txx1 = txxs[i];
                    }
                    else if (CsOthers.IsEqual(txxs[i].TD, 1.5f))
                    {
                        txx2 = txxs[i];
                    }
                }
                if (Math.Abs(r) < 3.0f)
                {
                    txx = txx2;
                }
                else
                {
                    txx = txx1;
                }
            }
            //如果返回的数据中刀号为空,则刀径修改为零


            if (txx.T == null || txx.T == "")
            {
                txx.TD = 0;
            }
            return txx;
        }
        /// <summary>
        /// 绘制图像
        /// </summary>
        /// <param name="g"> GPI对象</param>
        /// <param name="p"> 画笔 </param>
        /// <param name="morX">X镜像</param>
        /// <param name="morY">Y镜像</param>
        public override void Draw(Graphics g, Pen p, bool morX, bool morY)
        {
            if (p == null)
            {
                p = new Pen(this.Color, 0.5f);
            }
            float x = Center.X - (R * 10000f / 25.4f);
            float y = Center.Y - (R * 10000f / 25.4f);
            float d = 2 * (R * 10000f / 25.4f);
            float startAngle;
 
            startAngle = PAngle(BnAngle, EdAngle, MdPoint, Center);
          
            float sweepAngle = RoundAngle;
           
            g.DrawArc(p, y, x, d, d, startAngle, sweepAngle);
            g.Dispose();
        }
        /// <summary>
        /// 绘制图像
        /// </summary>
        /// <param name="g">GPI对象</param>
        /// <param name="p">画笔</param>
        /// <param name="morX">X镜像</param>
        /// <param name="morY">Y镜像</param>
        /// <param name="absCenter">映射的坐标集合(相对+映射坐标计算在治具的坐标)</param>
        public override void Draw(Graphics g, Pen p, bool morX, bool morY, params Point[] absCenter)
        {
            if (p == null)
            {
                p = new Pen(this.Color, 0.5f);
            }
            Point pt = GetAbsCenter(morX, morY, absCenter);

            float x = pt.X - (R * 10000f / 25.4f);
            float y = pt.Y - (R * 10000f / 25.4f);
            float d = 2 * (R * 10000f / 25.4f);

            float startAngle;

            startAngle = PAngle(BnAngle, EdAngle, MdPoint, pt);

            float sweepAngle = RoundAngle;

            g.DrawArc(p, y, x, d, d, startAngle, sweepAngle);
        }
        /// <summary>
        /// 绘制图形
        /// </summary>
        /// <param name="g"></param>
        /// <param name="p"></param>
        /// <param name="morX"></param>
        /// <param name="morY"></param>
        /// <param name="angle"></param>
        /// <param name="absCenter"></param>
        public override void Draw(Graphics g, Pen p, bool morX, bool morY, float angle, params Point[] absCenter)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 绘制图像(正交镜像)
        /// </summary>
        /// <param name="g"></param>
        /// <param name="p"></param>
        /// <param name="morX"></param>
        /// <param name="morY"></param>
        /// <param name="sceX">x缩放比例</param>
        /// <param name="sceY">y缩放比例</param>
        /// <param name="absCenter"></param>
        public override void Draw(Graphics g, Pen p, bool morX, bool morY, bool sceX, bool sceY, bool abs, params Point[] absCenter)
        {
            if (p == null)
            {
                p = new Pen(this.Color, 0.5f);
            }
            Point cen, pt1, pt2, pt3;
            if (abs)
            {
                cen = GetAbsCenter(morX, morY, absCenter);
                pt1 = GetNewPoint(morX, morY, BnPoint, absCenter);
                pt2 = GetNewPoint(morX, morY, MdPoint, absCenter);
                pt3 = GetNewPoint(morX, morY, EdPoint, absCenter);
            }
            else
            {
                cen = GetAbsCenter(morX, morY, sceX, sceY, absCenter);
                pt1 = GetNewPoint(morX, morY, sceX, sceY, BnPoint, absCenter);
                pt2 = GetNewPoint(morX, morY, sceX, sceY, MdPoint, absCenter);
                pt3 = GetNewPoint(morX, morY, sceX, sceY, EdPoint, absCenter);
            }
            float x = cen.X - (R * 10000f / 25.4f);
            float y = cen.Y - (R * 10000f / 25.4f);
            float d = 2 * (R * 10000f / 25.4f);

            float start = PAngle(pt1, cen);
            float end = PAngle(pt3, cen);
            float startAngle = PAngle(start, end, pt2, cen);

            float sweepAngle = RoundAngle;

            g.DrawArc(p, y, x, d, d, startAngle, sweepAngle);

        }
        /// <summary>
        /// 框选圆弧元素

        /// </summary>
        /// <param name="cursorOriginX"></param>
        /// <param name="cursorOriginY"></param>
        /// <param name="cursorDestinationX"></param>
        /// <param name="cursorDestinationY"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        public override bool Set(int cursorOriginX, int cursorOriginY, int cursorDestinationX, int cursorDestinationY, float scale)
        {
          
            int[] x = new int[] { bnPoint.X, mdPoint.X, edPoint.X };
            int[] y = new int[] { bnPoint.Y, mdPoint.Y, edPoint.Y };

            int maxX = x[0], minX = x[0], maxY = y[0], minY = y[0];
            for (int i = 1; i < x.Length; i++)
            {
                if (minX > x[i])
                {
                    minX = x[i];
                }
                if (maxX < x[i])
                {
                    maxX = x[i];
                }
            }
            for (int i = 1; i < y.Length; i++)
            {
                if (minY > y[i])
                {
                    minY = y[i];
                }
                if (maxY < y[i])
                {
                    maxY = y[i];
                }
            }
            //计算出圆弧所在矩形的长度和宽度

            int heighty = Math.Abs(maxY - minY);
            int widthx = Math.Abs(maxX - minX);

            int cenx = (int)(maxX + minX) / 2;
            int ceny = (int)(maxY + minY) / 2;

            int rectanglewidth = (int)(Math.Abs(cursorDestinationX - cursorOriginX));//计算出框选矩形的宽度
            int rectangleheight = (int)(Math.Abs(cursorDestinationY - cursorOriginY));//计算出框选矩形的高度
            int rectanglecenterX = (int)(cursorOriginX + cursorDestinationX) / 2;//计算出框选矩形的中心点坐标

            int rectanglecenterY = (int)(cursorOriginY + cursorDestinationY) / 2;

            int xa = cenx - (int)widthx / 2;
            int ya = ceny - (int)heighty / 2;
            int xb = cenx + (int)widthx / 2;
            int yb = ceny + (int)heighty / 2;

            if (((rectanglecenterX - rectanglewidth / 2) <= xa) && (xa <= (rectanglecenterX + rectanglewidth / 2)) &&
                ((rectanglecenterY - rectangleheight / 2) <= ya) && (ya <= (rectanglecenterY + rectangleheight / 2)) &&
                ((rectanglecenterX - rectanglewidth / 2) <= xb) && (xb <= (rectanglecenterX + rectanglewidth / 2)) &&
                ((rectanglecenterY - rectangleheight / 2) <= yb) && (yb <= (rectanglecenterY + rectangleheight / 2)) &&
                widthx <= rectanglewidth && heighty <= rectangleheight)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="cursorOriginX"></param>
        /// <param name="cursorOriginY"></param>
        /// <param name="cursorDestinationX"></param>
        /// <param name="cursorDestinationY"></param>
        /// <param name="scale"></param>
        /// <param name="absCenter"></param>
        /// <returns></returns>
        public override bool Set(int cursorOriginX, int cursorOriginY, int cursorDestinationX, int cursorDestinationY, float scale, params Point[] absCenter)
        {
            int[] x = new int[] { bnPoint.X, mdPoint.X, edPoint.X };
            int[] y = new int[] { bnPoint.Y, mdPoint.Y, edPoint.Y };

            int maxX = x[0], minX = x[0], maxY = y[0], minY = y[0];
            for (int i = 1; i < x.Length; i++)
            {
                if (minX > x[i])
                {
                    minX = x[i];
                }
                if (maxX < x[i])
                {
                    maxX = x[i];
                }
            }
            for (int i = 1; i < y.Length; i++)
            {
                if (minY > y[i])
                {
                    minY = y[i];
                }
                if (maxY < y[i])
                {
                    maxY = y[i];
                }
            }
            //计算出圆弧所在矩形的长度和宽度

            int heighty = Math.Abs(maxY - minY);
            int widthx = Math.Abs(maxX - minX);

            //int cenx = (int)(maxX + minX) / 2;
            //int ceny = (int)(maxY + minY) / 2;


            int absX = center.X;
            int absY = center.Y;
            for (int i = 0; i < absCenter.Length; i++)
            {
                absX += absCenter[i].X;
                absY += absCenter[i].Y;
            }
            int rectanglewidth = (int)(Math.Abs(cursorDestinationX - cursorOriginX));
            int rectangleheight = (int)(Math.Abs(cursorDestinationY - cursorOriginY));
            int rectanglecenterX = (int)(cursorOriginX + cursorDestinationX) / 2;
            int rectanglecenterY = (int)(cursorOriginY + cursorDestinationY) / 2;

            int xa = absX - (int)widthx / 2;
            int ya = absY - (int)heighty / 2;
            int xb = absX + (int)widthx / 2;
            int yb = absY + (int)heighty / 2;

            if (((rectanglecenterX - rectanglewidth / 2) <= xa) && (xa <= (rectanglecenterX + rectanglewidth / 2)) &&
                ((rectanglecenterY - rectangleheight / 2) <= ya) && (ya <= (rectanglecenterY + rectangleheight / 2)) &&
                ((rectanglecenterX - rectanglewidth / 2) <= xb) && (xb <= (rectanglecenterX + rectanglewidth / 2)) &&
                ((rectanglecenterY - rectangleheight / 2) < yb) && (yb <= (rectanglecenterY + rectangleheight / 2)) &&
                widthx <= rectanglewidth && heighty <= rectangleheight)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 判断选中
        /// </summary>
        /// <param name="cursor">光标坐标</param>
        /// <param name="scale">缩放比例</param>
        /// <returns>是否选中(bool值)</returns>
        public override bool Set(Point cursor, float scale)
        {
            int x0 = (int)(cursor.X - center.X);
            int y0 = (int)(cursor.Y - center.Y);
            int r0 = (int)Math.Sqrt(Math.Pow(x0, 2) + Math.Pow(y0, 2));
            //计算角度
            float angle0 = PAngle(cursor, center);
            bool has = PAngle(BnAngle, MdPoint, EdAngle, angle0);
            if ((Math.Abs((int)(R * 10000f / 25.4f) - r0)) * scale <= 360 && has)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 判断选中零件
        /// </summary>
        /// <param name="cursorOriginX">鼠标起点X坐标</param>
        /// <param name="cursorOriginY">鼠标起点Y坐标</param>
        /// <param name="cursorDestinationX">鼠标终点X坐标</param>
        /// <param name="cursorDestinationY">鼠标终点Y坐标</param>
        /// <param name="scale">缩放比例</param>
        /// <param name="absCenter">相对零件的绝对坐标</param>
        /// <returns>是否选中(bool值)</returns>
        public override bool Set(Point cursor, float scale, bool sceX, bool sceY, params Point[] absCenter)
        {
            Point center0 = GetAbsCenter(false, false, sceX, sceY, absCenter);
            int x0 = (int)((cursor.X - center0.X));
            int y0 = (int)((cursor.Y - center0.Y));
            float angle0 = PAngle(cursor, center);
            bool has = PAngle(BnAngle, MdPoint, EdAngle, angle0);

            int eleR = (int)Math.Sqrt(Math.Pow(x0, 2) + Math.Pow(y0, 2));

            if (Math.Abs(eleR - (int)(R * 10000f / 25.4f)) * scale <= 360 && has)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 判断选中
        /// </summary>
        /// <param name="cursor">光标坐标</param>
        /// <param name="scale">缩放比例</param>
        /// <param name="absCenter">映射的坐标集合(相对+映射坐标计算在治具的坐标</param>
        /// <returns>是否选中(bool值)</returns>
        public override bool Set(Point cursor, float scale, params Point[] absCenter)
        {
            int absX = center.X;
            int absY = center.Y;
            for (int i = 0; i < absCenter.Length; i++)
            {
                absX += absCenter[i].X;
                absY += absCenter[i].Y;
            }
            int x0 = (int)((cursor.X - absX));
            int y0 = (int)((cursor.Y - absY));
            float angle0 = PAngle(cursor, center);
            bool has = PAngle(BnAngle, MdPoint, EdAngle, angle0);

            int eleR = (int)Math.Sqrt(Math.Pow(x0, 2) + Math.Pow(y0, 2));

            if (Math.Abs(eleR - (int)(R * 10000f / 25.4f)) * scale <= 360 && has)
            {
                return true;
            }
            return false;
        }
        public override bool Set(Point cursor, float scale, float angle, Point[] absCenter)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 判断选中
        /// </summary>
        /// <param name="cursor">光标坐标</param>
        /// <param name="partcenter">运用零件中心</param>
        /// <param name="scale">缩放比例</param>
        /// <returns>是否选中(bool值)</returns>
        public override bool Set(Point cursor, Point partcenter, float scale)
        {
            int eleX = (int)(center.X + partcenter.X);//元素相对于零件的X坐标
            int eleY = (int)(center.Y + partcenter.Y);//元素相对于零件的Y坐标
            int x0 = (int)((cursor.X - eleX));//零件中单个元素的X轴坐标


            int y0 = (int)((cursor.Y - eleY));//零件中单个元素的Y轴坐标


            float angle0 = PAngle(cursor, center);
            bool has = PAngle(BnAngle, MdPoint, EdAngle, angle0);

            int eleR = (int)Math.Sqrt(Math.Pow(x0, 2) + Math.Pow(y0, 2));

            if (Math.Abs(eleR - (int)(R * 10000f / 25.4f)) * scale <= 360 && has)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 框选判断选中(用于框选)
        /// </summary>
        /// <param name="cursorOriginX">鼠标的起点X坐标</param>
        /// <param name="cursorOriginY">鼠标的起点Y坐标</param>
        /// <param name="cursorDestinationX">鼠标的终点X坐标</param>
        /// <param name="cursorDestinationY">鼠标的终点Y坐标</param>
        /// <param name="angle">旋转角度</param>
        /// <param name="scale">缩放比例</param>
        /// <returns>是否选中(bool)</returns>
        public override bool Set(int cursorOriginX, int cursorOriginY, int cursorDestinationX, int cursorDestinationY, float angle, float scale)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 判断选中(用于框选零件)
        /// </summary>
        /// <param name="cursorOriginX">鼠标的起点X坐标</param>
        /// <param name="cursorOriginY">鼠标的起点Y坐标</param>
        /// <param name="cursorDestinationX">鼠标的终点X坐标</param>
        /// <param name="cursorDestinationY">鼠标的终点Y坐标</param>
        /// <param name="scale">缩放比例</param>
        /// <param name="absCenter">映射的坐标集合(相对+映射坐标计算在治具的坐标)</param>
        /// <returns>是否选中(boo值)</returns>
        public override bool Set(int cursorOriginX, int cursorOriginY, int cursorDestinationX, int cursorDestinationY, float scale, float angle, params Point[] absCenter)
        {
            throw new NotImplementedException();
        }
                #endregion

    }
}
 


版权声明:本文为ganqiyin原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。