Пример #1
0
        /// <summary>
        /// 求点P到P1P2连线的距离
        /// </summary>
        /// <param name="P1"></param>
        /// <param name="P2"></param>
        /// <param name="P"></param>
        /// <param name="Extent">是否超出,如false当最近点不在两点之间时返回最大值</param>
        /// <returns></returns>
        public static double ClosestDistance_P2L(WPoint2D P1, WPoint2D P2, WPoint2D P, bool Extent)
        {
            WVector2D v = P1.VectorTo(P);
            WVector2D r = new WVector2D(P2.X - P1.X, P2.Y - P1.Y);     /////P1-P2

            r = r.Normalize();
            double l          = P1.DistanceTo(P2);
            double dotProduct = v.DotProduct(r);

            if (!Extent)
            {
                if (dotProduct < 0 || dotProduct > l)
                {
                    return(double.MaxValue);
                }
            }
            else
            {
                if (dotProduct < 0)
                {
                    return(P1.DistanceTo(P));
                }
                if (dotProduct > l)
                {
                    return(P2.DistanceTo(P));
                }
            }

            WVector2D alongVector = dotProduct * r;
            WPoint2D  Pm          = P1 + alongVector;

            return(P.DistanceTo(Pm));
        }
Пример #2
0
        public static WPoint2D Intersection_L2L(WPoint2D P11, WPoint2D P12, WPoint2D P21, WPoint2D P22)
        {
            ///判断头尾点是否相连
            if (Geos2D_Other.Check_PsMerge(P11, P21) == true || Geos2D_Other.Check_PsMerge(P11, P22) == true)
            {
                return(P11);
            }
            if (Geos2D_Other.Check_PsMerge(P12, P21) == true || Geos2D_Other.Check_PsMerge(P12, P22) == true)
            {
                return(P12);
            }
            ///求交点
            WVector2D d1 = P11.VectorTo(P12);
            WVector2D d2 = P21.VectorTo(P22);

            if (d1.IsParallelTo(d2, WGeos2D_Paras.E_Angle))
            {
                return(null);
            }
            double t = (P21 - P11).CrossProduct(d2) / (d1.CrossProduct(d2));

            if (t < 0 || t > 1)
            {
                return(null);
            }
            WPoint2D P = P11 + t * d1;

            if (CheckBound_Single(P21.X, P22.X, P.X) == false || CheckBound_Single(P21.Y, P22.Y, P.Y) == false)
            {
                return(null);
            }
            return(P);
        }
Пример #3
0
        /// 求出每个点的内夹角
        private static void P2Ps_Angles(ref List <int>[] Ns, ref List <WVector2D>[] Vs, ref List <PAngle>[] As)
        {
            double[]    Ans;
            int[]       Nus;
            WVector2D[] Vns;
            double      Ant;
            int         Nut;
            WVector2D   Vnt;

            Array.Resize <List <PAngle> >(ref As, Ns.Length);
            for (int i = 0; i < Ns.Length; i++)
            {
                Ans    = new double[Ns[i].Count];
                Nus    = new int[Ns[i].Count];
                Vns    = new WVector2D[Ns[i].Count];
                Ans[0] = 0;
                Nus[0] = Ns[i][0];
                Vns[0] = Vs[i][0];
                /////赋值
                for (int j = 1; j < Ns[i].Count; j++)
                {
                    Ans[j] = Vs[i][0].AngleAntiCrossWiseTo(Vs[i][j]);
                    Nus[j] = Ns[i][j];
                    Vns[j] = Vs[i][j];
                }
                /////排序
                for (int j = 1; j < Ans.Length - 1; j++)
                {
                    for (int k = j + 1; k < Ans.Length; k++)
                    {
                        if (Ans[j] > Ans[k])
                        {
                            Ant    = Ans[k];
                            Nut    = Nus[k];
                            Vnt    = Vns[k];
                            Ans[k] = Ans[j];
                            Nus[k] = Nus[j];
                            Vns[k] = Vns[j];
                            Ans[k] = Ant;
                            Nus[j] = Nut;
                            Vns[j] = Vnt;
                        }
                    }
                }
                /////求取
                As[i] = new List <PAngle>();
                for (int j = 0; j < Ans.Length - 1; j++)
                {
                    As[i].Add(new PAngle(i, Nus[j], Nus[j + 1], Vns[j].AngleAntiCrossWiseTo(Vns[j + 1])));
                }
                As[i].Add(new PAngle(i, Nus[Ans.Length - 1], Nus[0], Vns[Ans.Length - 1].AngleAntiCrossWiseTo(Vns[0])));
            }
            Ans = null;
            Nus = null;
            Vns = null;
        }
Пример #4
0
        /// <summary>
        /// 点P到Poly的最近点
        /// </summary>
        /// <param name="P"></param>
        /// <param name="PL"></param>
        /// <param name="Extent">是否超出,如false当最近点不在两点之间时返回null</param>
        /// <returns></returns>
        public static WPoint2D ClosestPoint_P2PL(WPoint2D P, WPolyLine2D PL, bool Extent)
        {
            WVector2D v;                    /////P2-P
            WVector2D r;                    /////P2-P1
            double    dotProduct, dot0;
            WPoint2D  Po;                   /////用于输出的变量

            v          = PL[0].VectorTo(P); /////开始反向使用
            r          = PL[0].VectorTo(PL[1]).Normalize();
            dotProduct = v.DotProduct(r);
            if (dotProduct <= 0)       /////这决定了该函数只能用在不复杂的情况
            {
                if (!Extent)
                {
                    return(null);
                }
                else
                {
                    Po          = PL[0];
                    Po.CheckNum = 0;
                    return(Po);
                }
            }

            dot0 = dotProduct;

            for (int i = 1; i < PL.Count; i++)
            {
                v          = PL[i].VectorTo(P);
                r          = PL[i].VectorTo(PL[i - 1]).Normalize();
                dotProduct = v.DotProduct(r);

                if (dotProduct >= 0)
                {
                    double    l           = PL[i - 1].DistanceTo(PL[i]);
                    WVector2D alongVector = dot0 * r.Negate();
                    Po          = PL[i - 1] + alongVector;
                    Po.CheckNum = i - 1;   /////输出时将该点的之前节点的编号也输出,利于下一步使用
                    return(Po);
                }
                dot0 = dotProduct * -1;
            }

            if (!Extent)
            {
                return(null);
            }
            else
            {
                Po          = PL[PL.Count - 1];
                Po.CheckNum = PL.Count - 2;
                return(Po);
            }
        }
Пример #5
0
        /// <summary>
        /// 求点P到Poly的距离
        /// </summary>
        /// <param name="P"></param>
        /// <param name="PL"></param>
        /// <param name="Extent">是否超出,如false当最近点不在两点之间时返回最大值</param>
        /// <returns></returns>
        public static double ClosestDistance_P2PL(WPoint2D P, WPolyLine2D PL, bool Extent)
        {
            WVector2D v; /////P2-P
            WVector2D r; /////P2-P1
            double    dotProduct, dot0;

            v          = PL[0].VectorTo(P); /////开始反向使用
            r          = PL[0].VectorTo(PL[1]).Normalize();
            dotProduct = v.DotProduct(r);
            if (dotProduct <= 0)       /////这决定了该函数只能用在不复杂的情况
            {
                if (!Extent)
                {
                    return(double.MaxValue);
                }
                else
                {
                    return(PL[0].DistanceTo(P));
                }
            }

            dot0 = dotProduct;

            for (int i = 1; i < PL.Count; i++)
            {
                v          = PL[i].VectorTo(P);
                r          = PL[i].VectorTo(PL[i - 1]).Normalize();
                dotProduct = v.DotProduct(r);

                if (dotProduct >= 0)
                {
                    double    l           = PL[i - 1].DistanceTo(PL[i]);
                    WVector2D alongVector = dot0 * r.Negate();
                    WPoint2D  Pm          = PL[i - 1] + alongVector;
                    return(Pm.DistanceTo(P));
                }
                dot0 = dotProduct * -1;
            }

            if (!Extent)
            {
                return(double.MaxValue);
            }
            else
            {
                return(PL[PL.Count - 1].DistanceTo(P));
            }
        }
Пример #6
0
        private static bool Check_Reverse(int N1, int N2, int N3, List <WPoint2D> Ps)
        {
            WPoint2D  O  = new WPoint2D((Ps[N1].X + Ps[N2].X + Ps[N3].X) / 3, (Ps[N1].Y + Ps[N2].Y + Ps[N3].Y) / 3, 0);
            WVector2D V1 = O.VectorTo(Ps[N1]);
            WVector2D V2 = O.VectorTo(Ps[N2]);
            WVector2D V3 = O.VectorTo(Ps[N3]);
            double    A2 = V1.AngleAntiCrossWiseTo(V2);
            double    A3 = V1.AngleAntiCrossWiseTo(V3);

            if (A2 > A3)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #7
0
        private static List <WPoint2D> Dotline_Times(WLine2D L, WPoint2D P1, WPoint2D P2, int Times)
        {
            List <WPoint2D> Ps = new List <WPoint2D>();

            Ps.Add(P1);
            WVector2D v = P1.VectorTo(P2);
            double    l = v.Length / Times;

            v = v.Normalize();
            WPoint2D P = P1;

            for (int i = 1; i < Times; i++)
            {
                P = P + v * l;
                Ps.Add(P);
            }
            Ps.Add(P2);
            return(Ps);
        }
Пример #8
0
        /// <summary>
        /// 划分直线段
        /// </summary>
        /// <param name="L"></param>
        /// <param name="Times">实际输出的点集有Times+1个点,从0到Times</param>
        /// <returns></returns>
        private static List <WPoint2D> Dotline_Times(WLine2D L, int Times)
        {
            List <WPoint2D> Ps = new List <WPoint2D>();

            Ps.Add(L.StartPoint);
            WVector2D v = L.StartPoint.VectorTo(L.EndPoint);
            double    l = v.Length / Times;

            v = v.Normalize();
            WPoint2D P = L.StartPoint;

            for (int i = 1; i < Times; i++)
            {
                P = P + v * l;
                Ps.Add(P);
            }
            Ps.Add(L.EndPoint);
            return(Ps);
        }
Пример #9
0
        /// <summary>
        /// 点P到P1P2两点连线的最近点
        /// </summary>
        /// <param name="P1"></param>
        /// <param name="P2"></param>
        /// <param name="P"></param>
        /// <param name="Extent">是否超出,如false当最近点不在两点之间时返回null</param>
        /// <returns></returns>
        public static WPoint2D ClosestPoint_P2L(WPoint2D P1, WPoint2D P2, WPoint2D P, bool Extent)
        {
            WVector2D v = P1.VectorTo(P);
            WVector2D r = new WVector2D(P2.X - P1.X, P2.Y - P1.Y);     /////P1-P2

            r = r.Normalize();
            double l          = P1.DistanceTo(P2);
            double dotProduct = v.DotProduct(r);

            if (!Extent)
            {
                if (dotProduct < 0)
                {
                    return(null);
                }
                if (dotProduct > l)
                {
                    return(null);
                }
            }
            WVector2D alongVector = dotProduct * r;

            return(P1 + alongVector);
        }