/// <summary>
 /// 判断点与线的位置
 /// </summary>
 /// <param name="P">P点</param>
 /// <param name="Q">Q点</param>
 /// <param name="R">R点</param>
 /// <returns>返回偏转方向</returns>
 /// <remarks>
 /// 假设L线的是 P->Q PQ为线的2个顶点
 /// 返回值 大于 0 , 则PQ在R点拐向右侧后得到QR,等同于点R在PQ线段的右侧
 /// 返回值 小于 0 , 则PQ在R点拐向左侧后得到QR,等同于点R在PQ线段的左侧
 /// 返回值 等于 0 , 则P,Q,R三点共线。
 /// </remarks>
 public static Int32 Position(PointI P, PointI Q, PointI R)
 {
     //PointI RP = PointAlgorithm.Substract(R, P);//R-P
     //PointI QP = PointAlgorithm.Substract(Q, P);//Q-P
     //return PointAlgorithm.Multiple(RP, QP);
     return(PointAlgorithm.Multiple(P, Q, R));
 }
        /// <summary>
        /// 计算(R-P)和(Q-P)的叉积
        /// </summary>
        /// <param name="P">点P</param>
        /// <param name="Q">点Q</param>
        /// <param name="R">点R</param>
        /// <returns>返回叉积值</returns>
        /// <remarks>
        /// 返回值 大于0 R在矢量PQ的逆时针方向
        /// 返回值 等于0 R,P,Q 三点共线
        /// 返回值 小于0 R在矢量PQ的顺时针方向
        /// </remarks>
        public static Int32 Multiple(PointI P, PointI Q, PointI R)
        {
            PointI RP = PointAlgorithm.Substract(R, P); //R-P
            PointI QP = PointAlgorithm.Substract(Q, P); //Q-P

            return(PointAlgorithm.Multiple(RP, QP));
        }
 /// <summary>
 /// 判断点与线的位置
 /// </summary>
 /// <param name="P">P点</param>
 /// <param name="Q">Q点</param>
 /// <param name="R">R点</param>
 /// <returns>返回偏转方向</returns>
 /// <remarks>
 /// 假设L线的是 P->Q PQ为线的2个顶点
 /// 返回值 大于 0 , 则PQ在R点拐向右侧后得到QR,等同于点R在PQ线段的右侧
 /// 返回值 小于 0 , 则PQ在R点拐向左侧后得到QR,等同于点R在PQ线段的左侧
 /// 返回值 等于 0 , 则P,Q,R三点共线。
 /// </remarks>
 public static Double Position(PointD P, PointD Q, PointD R)
 {
     //PointD RP = PointAlgorithm.Substract(R, P);//R-P
     //PointD QP = PointAlgorithm.Substract(Q, P);//Q-P
     //return PointAlgorithm.Multiple(RP, QP);
     return(PointAlgorithm.Multiple(P, Q, R));
 }
        /// <summary>
        /// 计算(R-P)和(Q-P)的叉积
        /// </summary>
        /// <param name="P">点P</param>
        /// <param name="Q">点Q</param>
        /// <param name="R">点R</param>
        /// <returns>返回叉积值</returns>
        /// <remarks>
        /// 返回值 大于0 R在矢量PQ的逆时针方向
        /// 返回值 等于0 R,P,Q 三点共线
        /// 返回值 小于0 R在矢量PQ的顺时针方向
        /// </remarks>
        public static Double Multiple(PointD P, PointD Q, PointD R)
        {
            PointD RP = PointAlgorithm.Substract(R, P); //R-P
            PointD QP = PointAlgorithm.Substract(Q, P); //Q-P

            return(PointAlgorithm.Multiple(RP, QP));
        }
Exemple #5
0
        /// <summary>
        /// 判断点P是否在圆内
        /// </summary>
        /// <param name="C">圆C</param>
        /// <param name="P">点P</param>
        /// <returns>如果在圆内返回True,否则返回False。</returns>
        public static Boolean InCircle(CircleI C, PointI P)
        {
            //判断点是否在圆内:
               //计算圆心到该点的距离,如果小于等于半径则该点在圆内。
            Double D = PointAlgorithm.Distance(P, C.Center);

            return((D < C.Radius) || DoubleAlgorithm.Equals(D, C.Radius));
        }
        /// <summary>
        /// 计算多边形PG面积
        /// </summary>
        /// <param name="PG">多边形PG</param>
        /// <returns>返回面积。</returns>
        public static Double Area(PolygonI PG)
        {
            //formula  (1/2) *( (Xi*Yi+1 -Xi+1*Yi) +...)
            Double result = 0;

            for (Int32 i = 0; i < PG.Vertex.Count; ++i)
            {
                result += PointAlgorithm.Multiple(PG.Vertex[i % PG.Vertex.Count], PG.Vertex[(i + 1) % PG.Vertex.Count]);
            }
            return(System.Math.Abs(0.5 * result));
        }
        /// <summary>
        /// 判断折线的偏转方向/线段拐向
        /// </summary>
        /// <param name="P">P点</param>
        /// <param name="Q">Q点</param>
        /// <param name="R">R点</param>
        /// <returns>返回偏转方向</returns>
        /// <remarks>
        /// 返回值 大于 0 , 则PQ在R点拐向右侧后得到QR,等同于点R在PQ线段的右侧
        /// 返回值 小于 0 , 则PQ在R点拐向左侧后得到QR,等同于点R在PQ线段的左侧
        /// 返回值 等于 0 , 则P,Q,R三点共线。
        /// </remarks>
        public static Int32 DeflectingDirection(PointI P, PointI Q, PointI R)
        {
            //formular
            //折线段的拐向判断方法可以直接由矢量叉积的性质推出。对于有公共端点的线段PQ和QR,通过计算(R - P) * (Q - P)的符号便可以确定折线段的拐向
            //基本算法是(R-P)计算相对于P点的R点坐标,(Q-P)计算相对于P点的Q点坐标。
            //(R-P) * (Q-P)的计算结果是计算以P为相对原点,点R与点Q的顺时针,逆时针方向。
            PointI RP = PointAlgorithm.Substract(R, P); //R-P
            PointI QP = PointAlgorithm.Substract(Q, P); //Q-P

            return(PointAlgorithm.Multiple(RP, QP));
        }
Exemple #8
0
 /// <summary>
 /// 判断折线PL是否在圆内
 /// </summary>
 /// <param name="C">圆C</param>
 /// <param name="R">矩形R</param>
 /// <returns>如果在圆内返回True,否则返回False。</returns>
 public static Boolean InCircle(CircleI C, RectangleI R)
 {
     if (PointAlgorithm.Distance(new PointI(R.Left, R.Top), C.Center) > C.Radius)
     {
         return(false);
     }
     if (PointAlgorithm.Distance(new PointI(R.Right, R.Bottom), C.Center) > C.Radius)
     {
         return(false);
     }
     return(true);
 }
        /// <summary>
        /// 获取线段L与圆C的交点集合
        /// </summary>
        /// <param name="L">线段L</param>
        /// <param name="C">圆C</param>
        /// <returns>返回交点集合.</returns>
        public static PointD[] Intersection(LineI L, CircleI C)
        {
            List <PointD> result = new List <PointD>();
            Int32?        has    = HasIntersection(L, C);

            if (has == 0 || has == null)
            {
                return(result.ToArray());
            }

            //Points P (x,y) on a line defined by two points P1 (x1,y1,z1) and P2 (x2,y2,z2) is described by
            //P = P1 + u (P2 - P1)

            //or in each coordinate
            //x = x1 + u (x2 - x1)
            //y = y1 + u (y2 - y1)
            //z = z1 + u (z2 - z1)

            //A sphere centered at P3 (x3,y3,z3) with radius r is described by
            //(x - x3)2 + (y - y3)2 + (z - z3)2 = r2

            //Substituting the equation of the line into the sphere gives a quadratic equation of the form
            //a u2 + b u + c = 0

            //where:
            //a = (x2 - x1)2 + (y2 - y1)2 + (z2 - z1)2

            //b = 2[ (x2 - x1) (x1 - x3) + (y2 - y1) (y1 - y3) + (z2 - z1) (z1 - z3) ]

            //c = x32 + y32 + z32 + x12 + y12 + z12 - 2[x3 x1 + y3 y1 + z3 z1] - r2


            //The solutions to this quadratic are described by
            PointD PD = PointAlgorithm.Substract(L.Starting, L.End);
            Double a  = PD.X * PD.X + PD.Y * PD.Y;
            Double b  = 2 * ((L.End.X - L.Starting.X) * (L.Starting.X - C.Center.X) + (L.End.Y - L.Starting.Y) * (L.Starting.Y - C.Center.Y));
            Double c  = C.Center.X * C.Center.X + C.Center.Y * C.Center.Y + L.Starting.X * L.Starting.X + L.Starting.Y * L.Starting.Y - 2 * (C.Center.X * L.Starting.X + C.Center.Y * L.Starting.Y) - C.Radius * C.Radius;
            Double u1 = ((-1) * b + System.Math.Sqrt(b * b - 4 * a * c)) / (2 * a);
            Double u2 = ((-1) * b - System.Math.Sqrt(b * b - 4 * a * c)) / (2 * a);
            //交点
            PointD P1 = new PointD(L.Starting.X + u1 * (L.End.X - L.Starting.X), L.Starting.Y + u1 * (L.End.Y - L.Starting.Y));
            PointD P2 = new PointD(L.Starting.X + u2 * (L.End.X - L.Starting.X), L.Starting.Y + u2 * (L.End.Y - L.Starting.Y));

            if (LineAlgorithm.OnLine(L, P1) == true)
            {
                result.Add(P1);
            }
            if (LineAlgorithm.OnLine(L, P2) == true && P1.Equals(P2) == false)
            {
                result.Add(P2);
            }
            return(result.ToArray());
        }
 /// <summary>
 /// 判断折线的偏转方向/线段拐向
 /// </summary>
 /// <param name="L">L线段</param>
 /// <param name="R">R点</param>
 /// <returns>返回偏转方向</returns>
 /// <remarks>
 /// 假设L线的是 P->Q PQ为线的2个顶点
 /// 返回值 大于 0 , 则PQ在R点拐向右侧后得到QR,等同于点R在PQ线段的右侧
 /// 返回值 小于 0 , 则PQ在R点拐向左侧后得到QR,等同于点R在PQ线段的左侧
 /// 返回值 等于 0 , 则P,Q,R三点共线。
 /// </remarks>
 public static Int32 Position(LineI L, PointI R)
 {
     //formular
     //折线段的拐向判断方法可以直接由矢量叉积的性质推出。对于有公共端点的线段PQ和QR,通过计算(R - P) * (Q - P)的符号便可以确定折线段的拐向
     //基本算法是(R-P)计算相对于P点的R点坐标,(Q-P)计算相对于P点的Q点坐标。
     //(R-P) * (Q-P)的计算结果是计算以P为相对原点,点R与点Q的顺时针,逆时针方向。
     //PointI P = L.Starting;
     //PointI Q = L.End;
     //PointI RP = PointAlgorithm.Substract(R, P);//R-P
     //PointI QP = PointAlgorithm.Substract(Q, P);//Q-P
     //return PointAlgorithm.Multiple(RP, QP);
     return(PointAlgorithm.Multiple(L.Starting, L.End, R));
 }
Exemple #11
0
 /// <summary>
 /// 判断线段L是否在圆内
 /// </summary>
 /// <param name="C">圆C</param>
 /// <param name="L">线段L</param>
 /// <returns>如果在圆内返回True,否则返回False。</returns>
 public static Boolean InCircle(CircleD C, LineD L)
 {
     //判断点是否在圆内:
        //计算圆心到该点的距离,如果小于等于半径则该点在圆内。
     if (PointAlgorithm.Distance(L.Starting, C.Center) > C.Radius)
     {
         return(false);
     }
     if (PointAlgorithm.Distance(L.End, C.Center) > C.Radius)
     {
         return(false);
     }
     return(true);
 }
        /// <summary>
        /// 判断圆C是否在多边形PG内
        /// </summary>
        /// <param name="PG">PG多边形</param>
        /// <param name="C">圆C</param>
        /// <returns>如果圆C在区域内返回True,否则返回False.</returns>
        public static Boolean InPolygon(PolygonI PG, CircleI C)
        {
            //如果圆心不在多边形内则返回不在多边形内
            if (false == InPolygon(PG, C.Center))
            {
                return(false);
            }
            Double D = PointAlgorithm.ClosestDistance(C.Center, PG);

            if (D > C.Radius || DoubleAlgorithm.Equals(D, C.Radius))
            {
                return(true);
            }
            return(false);
        }
Exemple #13
0
 /// <summary>
 /// 判断折线PL是否在圆内
 /// </summary>
 /// <param name="C">圆C</param>
 /// <param name="PL">折线PL</param>
 /// <returns>如果在圆内返回True,否则返回False。</returns>
 public static Boolean InCircle(CircleI C, PolylineI PL)
 {
     if (PL.Points == null)
     {
         return(false);
     }
     for (Int32 i = 0; i < PL.Points.Count; ++i)
     {
         if (PointAlgorithm.Distance(PL.Points[i], C.Center) > C.Radius)
         {
             return(false);
         }
     }
     return(true);
 }
Exemple #14
0
 /// <summary>
 /// 判断多边形PG是否在圆内
 /// </summary>
 /// <param name="C">圆C</param>
 /// <param name="PG">多边形PG</param>
 /// <returns>如果在圆内返回True,否则返回False。</returns>
 public static Boolean InCircle(CircleI C, PolygonI PG)
 {
     if (PG.Vertex == null)
     {
         return(false);
     }
     for (Int32 i = 0; i < PG.Vertex.Count; ++i)
     {
         if (PointAlgorithm.Distance(PG.Vertex[i], C.Center) > C.Radius)
         {
             return(false);
         }
     }
     return(true);
 }
Exemple #15
0
        /// <summary>
        /// 根据点P,Q,R三点确定一个圆,注意三点不能共线
        /// </summary>
        /// <param name="P">点P</param>
        /// <param name="Q">点Q</param>
        /// <param name="R">点R</param>
        /// <returns>返回圆,如果圆不存在则返回null.</returns>
        public static CircleD?CreateCircle(PointI P, PointI Q, PointI R)
        {
            if (DoubleAlgorithm.Equals(LineAlgorithm.Position(P, Q, R), 0))
            {
                return(null);                                                          //三点共线无法确定圆
            }
            //formula
            //(x-a)^2+(y-b)^2=r^2
            //f1:(x1-a)^2 + (y1-b)^2 = r^2
            //f2:(x2-a)^2 + (y2-b)^2 = r^2
            //f3:(x3-a)^2 + (y3-b)^2 = r^2
            //f1=f2: x1^2-2ax1+y1^2-2by1= x2^2-2ax2+y2^2-2by2;
            //a=(((X(1)^2-X(2)^2+Y(1)^2-Y(2)^2)*(Y(2)-Y(3)))-((X(2)^2-X(3)^2+Y(2)^2-Y(3)^2)*(Y(1)-Y(2))))/(2*(X(1)-X(2))*(Y(2)-Y(3))-2*(X(2)-X(3))*(Y(1)-Y(2)))
            //b=(((X(1)^2-X(2)^2+Y(1)^2-Y(2)^2)*(X(2)-X(3)))-((X(2)^2-X(3)^2+Y(2)^2-Y(3)^2)*(X(1)-X(2))))/(2*(Y(1)-Y(2))*(X(2)-X(3))-2*(Y(2)-Y(3))*(X(1)-X(2)))
            Double a = (Double)(((P.X * P.X - Q.X * Q.X + P.Y * P.Y - Q.Y * Q.Y) * (Q.Y - R.Y)) - ((Q.X * Q.X - R.X * R.X + Q.Y * Q.Y - R.Y * R.Y) * (P.Y - Q.Y))) / (Double)(2 * (P.X - Q.X) * (Q.Y - R.Y) - 2 * (Q.X - R.X) * (P.Y - Q.Y));
            Double b = (Double)(((P.X * P.X - Q.X * Q.X + P.Y * P.Y - Q.Y * Q.Y) * (Q.X - R.X)) - ((Q.X * Q.X - R.X * R.X + Q.Y * Q.Y - R.Y * R.Y) * (P.X - Q.X))) / (Double)(2 * (P.Y - Q.Y) * (Q.X - R.X) - 2 * (Q.Y - R.Y) * (P.X - Q.X));
            Double r = PointAlgorithm.Distance(P, new PointD(a, b));

            return(new CircleD(a, b, r));
        }
        /// <summary>
        /// 判断线段L与圆C的交点个数
        /// </summary>
        /// <param name="L">线段L</param>
        /// <param name="C">圆形C</param>
        /// <returns>相交返回交点数目,否则返回0</returns>
        public static Int32?HasIntersection(LineI L, CircleI C)
        {
            Int32 count = 0;

            //如果和圆C有交点首先是L到圆心的距离小于或等于C的半径
            if (DoubleAlgorithm.Equals(PointAlgorithm.ClosestDistance(C.Center, L), C.Radius))
            {
                return(1);
            }
            else if (PointAlgorithm.ClosestDistance(C.Center, L) > C.Radius)
            {
                return(0);
            }
            if (PointAlgorithm.Distance(C.Center, L.Starting) >= C.Radius)
            {
                ++count;
            }
            if (PointAlgorithm.Distance(C.Center, L.End) >= C.Radius)
            {
                ++count;
            }
            return(count);
        }
        /// <summary>
        /// 线段L是否在多边形区域内
        /// </summary>
        /// <param name="PG">多边形PG</param>
        /// <param name="L">线段L</param>
        /// <returns>如果线段L在区域内返回True,否则返回False.</returns>
        public static Boolean InPolygon(PolygonI PG, LineI L)
        {
            //if 线端PQ的端点不都在多边形内
            //  then return false;
            //点集pointSet初始化为空;
            //for 多边形的每条边s
            //  do if 线段的某个端点在s上
            //       then 将该端点加入pointSet;
            //     else if s的某个端点在线段PQ上
            //       then 将该端点加入pointSet;
            //     else if s和线段PQ相交 // 这时候已经可以肯定是内交了
            //       then return false;
            //将pointSet中的点按照X-Y坐标排序;
            //for pointSet中每两个相邻点 pointSet[i] , pointSet[ i+1]
            //  do if pointSet[i] , pointSet[ i+1] 的中点不在多边形中
            //       then return false;
            //return true;
            List <PointI> PointList = new List <PointI>();

            if (InPolygon(PG, L.Starting) == false)
            {
                return(false);
            }
            foreach (LineI S in PG)
            {
                if (LineAlgorithm.OnLine(S, L.Starting) == true)
                {
                    PointList.Add(L.Starting);
                }
                else if (LineAlgorithm.OnLine(S, L.End) == true)
                {
                    PointList.Add(L.End);
                }
                else if (LineAlgorithm.OnLine(L, S.Starting) == true)
                {
                    PointList.Add(S.Starting);
                }
                else if (LineAlgorithm.OnLine(L, S.End) == true)
                {
                    PointList.Add(S.End);
                }
                else if (LineAlgorithm.HasIntersection(L, S) > 0)
                {
                    return(false);
                }
            }
            PointI[] OrderedPointList = PointList.ToArray();
            for (Int32 i = 0; i < (OrderedPointList.Length - 1); ++i)
            {
                for (Int32 j = 0; j < (OrderedPointList.Length - i - 1); j++)
                {
                    MinMax <PointI> MM = new MinMax <PointI>(OrderedPointList[j], OrderedPointList[j + 1]);
                    OrderedPointList[j]     = MM.Min;
                    OrderedPointList[j + 1] = MM.Max;
                }
            }
            for (Int32 i = 0; i < (OrderedPointList.Length - 1); ++i)
            {
                if (false == InPolygon(PG, PointAlgorithm.MidPoint(OrderedPointList[i], OrderedPointList[i + 1])))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #18
0
 /// <summary>
 /// 计算点到圆的距离
 /// </summary>
 /// <param name="C">圆C</param>
 /// <param name="P">点P</param>
 /// <returns>返回点到圆周的距离。</returns>
 /// <remarks>
 /// 返回值小于0 表示点在圆内。
 /// 返回值等于0 表示点在圆周上。
 /// 返回值大于0 表示点在圆外。
 /// </remarks>
 public static Double Distance(CircleI C, PointI P)
 {
     return(PointAlgorithm.Distance(C.Center, P) - C.Radius);
 }
 /// <summary>
 /// 计算线段L与X轴的夹角
 /// </summary>
 /// <param name="L">线段L</param>
 /// <returns>返回夹角弧度</returns>
 public static Double IncludedAngle(LineD L)
 {
     return(PointAlgorithm.Angle(L.Starting, L.End, new PointD(10000000, L.Starting.Y)));
 }
Exemple #20
0
 /// <summary>
 /// 判断圆C2是否在圆C1内
 /// </summary>
 /// <param name="C1">圆C1</param>
 /// <param name="C2">圆C2</param>
 /// <returns>如果在圆内返回True,否则返回False。</returns>
 public static Boolean InCircle(CircleI C1, CircleI C2)
 {
     //formula
     //C2的中心点到C1中心点的距离 加上C2的半径小于C1的半径
     return(((PointAlgorithm.Distance(C1.Center, C2.Center) + C2.Radius) > C1.Radius) ? false : true);
 }
Exemple #21
0
 /// <summary>
 /// 计算线L到圆C的距离
 /// </summary>
 /// <param name="C">圆C</param>
 /// <param name="L">线L</param>
 /// <returns>返回线到圆周的距离。</returns>
 /// <remarks>
 /// 返回值小于0 表示线在圆内或与圆周相交。
 /// 返回值等于0 表示线在圆周上与圆周相切。
 /// 返回值大于0 表示线在圆外与圆周没有交点。
 /// </remarks>
 public static Double Distance(CircleI C, LineI L)
 {
     return(PointAlgorithm.Distance(C.Center, L) - C.Radius);
 }