/// <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)); }
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); }
/// 求出每个点的内夹角 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; }
/// <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); } }
/// <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)); } }
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); } }
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); }
/// <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); }
/// <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); }