Esempio n. 1
0
        //获取点集中,与指定点距离最大的点下标
        private int GetMaxDistancePointIndex(ShootPoint P, ref List <ShootPoint> Points)
        {
            //构造间距(平方)序列
            double[] Mat = new double[Points.Count];

            //中间变量
            ShootPoint TempPoint;
            double     DeltaX = 0;
            double     DeltaY = 0;

            //填充序列
            for (int i = 0; i < Points.Count; i++)
            {
                //获取对应的点
                TempPoint = Points.ElementAt(i);

                //计算坐标增量
                DeltaX = TempPoint.X_Pos - P.X_Pos;
                DeltaY = TempPoint.Y_Pos - P.Y_Pos;

                //获取两点间距的平方(因为最终只是比大小,所以省去了开方这一步骤用以节省运算量)
                Mat[i] = DeltaX * DeltaX + DeltaY * DeltaY;
            }

            //遍历间距序列,找到值最大的元素
            return(Array.IndexOf(Mat, Mat.Max()));
        }
Esempio n. 2
0
        //判断某点是否在圆范围内(在圆上和在圆内都算在圆范围内)
        public bool isInThisCircle(ShootPoint Point)
        {
            double DeltaX = Point.X_Pos - Center.X_Pos;
            double DeltaY = Point.Y_Pos - Center.Y_Pos;

            //忽略0.01mm以内的偏差,防止出现边界情况导致错误
            return((this.radius * this.radius + 1e-04) >= (DeltaX * DeltaX + DeltaY * DeltaY));
        }
Esempio n. 3
0
        //以两点连线作为直径构造圆
        public Circle(ShootPoint Point1, ShootPoint Point2)
        {
            //获取圆心坐标
            double Center_X = (Point1.X_Pos + Point2.X_Pos) / 2;
            double Center_Y = (Point1.Y_Pos + Point2.Y_Pos) / 2;

            center = new ShootPoint(Center_X, Center_Y);

            //计算半径
            double DeltaX = center.X_Pos - Point2.X_Pos;
            double DeltaY = center.Y_Pos - Point2.Y_Pos;

            radius = Math.Sqrt(DeltaX * DeltaX + DeltaY * DeltaY);
        }
Esempio n. 4
0
        //画一个点(此单位为mm,将在内部进行转换)
        private void DrawPoint(ShootPoint P, Color color)
        {
            //申请一个蓝画刷
            Pen      pen   = new Pen(color);
            Graphics Grphc = this.GrphcBuf.Graphics;

            //反向映射
            int Point_X = (int)(P.X_Pos / mm_PixelRate_X);
            int Point_Y = (int)(P.Y_Pos / mm_PixelRate_Y);

            //获得外框矩形参数
            Rectangle RecCenter = new Rectangle(Point_X - 4, Point_Y - 4, 8, 8);

            //画圆心
            Grphc.FillEllipse(pen.Brush, RecCenter);

            //从缓冲区输出至图框
            this.GrphcBuf.Render();
        }
Esempio n. 5
0
        //以三个不共线的点确定的三角形构造圆,此时圆为三角形的外接圆
        //若共线,则按照无参数方式构造空圆
        public Circle(ShootPoint Point1, ShootPoint Point2, ShootPoint Point3)
        {
            //求从点1出发指向点2、3的向量
            Vector2 Vec_1 = new Vector2(Point1, Point2);
            Vector2 Vec_2 = new Vector2(Point1, Point3);

            //如果斜率差小于一定阈值,则认为是一条直线
            if (Vec_1.isCollinear(Vec_2))
            {
                center = new ShootPoint(0, 0);
                radius = 0;
            }
            else
            {
                //求从点1出发指向点2、3向量的正交向量,作为其连线中垂线的方向向量
                Vector2 Vector_1 = Vec_1.GetOrthogonalVector();
                Vector2 Vector_2 = Vec_2.GetOrthogonalVector();

                //获取两直线中点
                ShootPoint CenterPoint1 = new ShootPoint((Point1.X_Pos + Point2.X_Pos) / 2, (Point1.Y_Pos + Point2.Y_Pos) / 2);
                ShootPoint CenterPoint2 = new ShootPoint((Point1.X_Pos + Point3.X_Pos) / 2, (Point1.Y_Pos + Point3.Y_Pos) / 2);

                ///则直线参数方程可以是:直线上某点P = CenterPoint + k * Vector_1.其中,k为任意实数。
                //据参数方程求中垂线交点参数
                double k1 = (Vector_2.X * (CenterPoint1.Y_Pos - CenterPoint2.Y_Pos)
                             + Vector_2.Y * (CenterPoint2.X_Pos - CenterPoint1.X_Pos))
                            / (Vector_1.X * Vector_2.Y - Vector_2.X * Vector_1.Y);

                //求得交点坐标,即为圆心坐标
                center = new ShootPoint(new Vector2(CenterPoint1) + k1 * Vector_1);

                ///验证正确性用
                //double k2 = (k1 * Vector_1.Y + CenterPoint1.Y_Pos - CenterPoint2.Y_Pos) / Vector_2.Y;
                //ShootPoint CheckCenter = new ShootPoint(new Vector2(CenterPoint2) + k2 * Vector_2);

                //计算半径
                double DeltaX = Point1.X_Pos - Center.X_Pos;
                double DeltaY = Point1.Y_Pos - Center.Y_Pos;

                radius = Math.Sqrt(DeltaX * DeltaX + DeltaY * DeltaY);
            }
        }
Esempio n. 6
0
 public Vector2(ShootPoint Src, ShootPoint Aim)
 {
     x = Aim.X_Pos - Src.X_Pos;
     y = Aim.Y_Pos - Src.Y_Pos;
 }
Esempio n. 7
0
 public Vector2(ShootPoint Point)
 {
     x = Point.X_Pos;
     y = Point.Y_Pos;
 }
Esempio n. 8
0
 //构造空圆
 public Circle()
 {
     center = new ShootPoint(0, 0);
     radius = 0;
 }
Esempio n. 9
0
 //以圆心和半径构造圆
 public Circle(ShootPoint Center, double R)
 {
     center = Center;
     radius = R;
 }
Esempio n. 10
0
        //从已经确定在圆上的一点和其他三点中确定最小包络圆
        private Circle GetNewCircle(ShootPoint P_Certain, ref List <ShootPoint> CirclePoints)
        {
            List <ShootPoint> Points    = new List <ShootPoint>();
            List <ShootPoint> AllPoints = CirclePoints.GetRange(0, CirclePoints.Count);

            //添加必在圆上的点到点集中
            Points.Add(P_Certain);
            AllPoints.Add(P_Certain);

            //第一轮尝试
            Points.Add(CirclePoints.ElementAt(0));
            Points.Add(CirclePoints.ElementAt(1));

            //求出此三点的最小包络圆
            Circle MinCircle = GetMinCircleOf3Points(ref Points);

            //判断是否包含所有点
            if (isAllPointsInCircle(ref AllPoints, MinCircle))
            {
                //仅保留在圆上的点,用于优化算法运行速度
                CirclePoints = Points;

                return(MinCircle);
            }
            else if (CirclePoints.Count < 3)
            {
                //如果在圆上的点比3小,就说明用于输入函数的点一定全拿来生成新圆了
                //如此还没通过上面的条件,那么一定是前面的运算中哪里算错了。
                return(new Circle());
            }


            //第二轮尝试
            if (Points.Count == 3)
            {
                //如果在生成上一个圆时,三个点都在圆上,拿掉最后面的点。
                Points.RemoveAt(2);
            }
            Points.Add(CirclePoints.ElementAt(2));

            //求出此三点的最小包络圆
            MinCircle = GetMinCircleOf3Points(ref Points);

            //判断是否包含所有点
            if (isAllPointsInCircle(ref AllPoints, MinCircle))
            {
                //仅保留在圆上的点,用于优化算法运行速度
                CirclePoints = Points;

                return(MinCircle);
            }

            //最后一轮尝试
            if (Points.Count == 3)
            {
                //如果在生成上一个圆时,三个点都在圆上,拿掉1点。
                Points.RemoveAt(1);
            }
            Points.Add(CirclePoints.ElementAt(1));

            //求出此三点的最小包络圆
            MinCircle = GetMinCircleOf3Points(ref Points);

            //判断是否包含所有点
            if (isAllPointsInCircle(ref AllPoints, MinCircle))
            {
                //仅保留在圆上的点,用于优化算法运行速度
                CirclePoints = Points;

                return(MinCircle);
            }

            //按道理讲不会到这里,若到了这里,说明出现了输入上的问题。
            return(new Circle());
        }