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); }
/// 单节点输出 /// <summary> /// 单节点输出 /// </summary> /// <param name="P"></param> /// <param name="Num"></param> /// <param name="sw"></param> public static void N_Out(WPoint2D P, int Num, ref StreamWriter sw) { sw.WriteLine(Convert.ToString(Num) + " "+ Convert.ToString(Math.Round(P.X, WGeos2D_Paras.Round)) + "," + Convert.ToString(Math.Round(P.Y, WGeos2D_Paras.Round)) + "," + Convert.ToString(P.CheckNum)); }
/// 将计算出夹丝线与边界线的交点加入边界线的节点中 private static void Add_Ps2_Bnds(ref List <WPoint2D> Pts, ref WCurve2D[] Bds_O) { for (int j = 0; j < Pts.Count; j++) { Bds_O[Pts[j].CheckNum].Nodes.Add(new WPoint2D(Pts[j].X, Pts[j].Y, 0)); for (int k = 0; k < Bds_O.Length; k++) { if (Bds_O[k].Meshed_Check == true) { continue; } if (k == Pts[j].CheckNum) { continue; } if (Geos2D_Other.Check_PsMerge(Pts[j], Bds_O[k].StartPoint) == true) { Bds_O[k].Nodes.Add(new WPoint2D(Pts[j].X, Pts[j].Y, 0)); } if (Geos2D_Other.Check_PsMerge(Pts[j], Bds_O[k].EndPoint) == true) { Bds_O[k].Nodes.Add(new WPoint2D(Pts[j].X, Pts[j].Y, 0)); } } Pts[j] = new WPoint2D(Pts[j].X, Pts[j].Y, 0); } }
private void Snap_Geo2DPoint(WPoint2D P, RenderData data) { Geo2D_Entities.Clear(); Geo2D_Temp.Clear(); try { if (data.PsList.Count == 0 || data.PsList == null) { return; } } catch { } ///// Geo2D_Temp = data.PsList.Point_Check(P, SnapPRange); if (Geo2D_Temp.Count == 0) { return; } ///// NumMin = Geo2D_Temp[0]; DisMin = double.MaxValue; for (int i = 0; i < Geo2D_Temp.Count; i++) { Dis = data.PsList[Geo2D_Temp[i]].DistanceTo(P); if (Dis < DisMin) { DisMin = Dis; NumMin = Geo2D_Temp[i]; } } Geo2D_Entities.Add(NumMin); }
/// <summary> /// 捕捉Rim /// </summary> /// <param name="P"></param> /// <param name="data"></param> private void Snap_Geo2DRim(WPoint2D P, RenderData data) { int N, NM; Geo2D_Rims.Clear(); ///// try { if (data.Rims.Count == 0 || data.Rims == null) { return; } } catch { } /////初步筛选 for (int i = 0; i < data.Rims.Count; i++) { if ((data.Rims[i]).Contains(P, 2f) == true) { Geo2D_Rims.Add(i); } } /////通过点与Rim关系进行再次筛选 for (int i = 0; i < Geo2D_Rims.Count; i++) { if (Check_PointInside(data.Rims[Geo2D_Rims[i]], P) == false) { Geo2D_Rims.RemoveAt(i); i--; } else { /////若找到一个最小级别的Rim则直接输出 if (data.Rims[Geo2D_Rims[i]].Smaller.Count == 0) { N = Geo2D_Rims[i]; Geo2D_Rims.Clear(); Geo2D_Rims.Add(N); break; } } } /////通过Smaller进行最后筛选 if (Geo2D_Rims.Count > 1) { NM = int.MaxValue; N = 0; for (int i = 0; i < Geo2D_Rims.Count; i++) { if (data.Rims[Geo2D_Rims[i]].Smaller.Count < NM) { NM = data.Rims[Geo2D_Rims[i]].Smaller.Count; N = i; } } N = Geo2D_Rims[N]; Geo2D_Rims.Clear(); Geo2D_Rims.Add(N); } }
/// <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)); }
/// 判断两点是否可以合并 /// <summary> /// 判断两点是否可以合并 /// </summary> public static bool Check_PsMerge(WPoint2D P1, WPoint2D P2) { if ((Math.Abs(P1.X - P2.X) < WGeos2D_Paras.E_Merge) && (Math.Abs(P1.Y - P2.Y) < WGeos2D_Paras.E_Merge)) { return(true); } return(false); }
/// <summary> /// 在Point上添加HardCheck属性 /// </summary> private WPoint2D Add_HardCheck(WPoint2D P, bool HardCheck) { if (P.HardCheck != true) { P.HardCheck = HardCheck; } return(P); }
public static WPoint2D ClosestPoint_P2C(WPoint2D P, WEntity2D C, bool Extent) { if (C.Kind == GeoKind.Line) { return(ClosestPoint_P2L(P, (WLine2D)C, Extent)); } return(ClosestPoint_P2PL(P, (WPolyLine2D)C, Extent)); }
/// 对夹丝边界线进行排序,从左至右输出竖向线 private static WEntity2D[] Sort_WBs(WLine2D AxisX, ref WEntity2D[] WBs, ref GLCommon GLC) { int Quan = WBs.Length; WPoint2D[] Ps = new WPoint2D[0]; /////夹丝边界线与横轴的交点点集 List <WPoint2D> Pst; WPoint2D P; int[] Ns = new int[0]; int N = 0; for (int i = 0; i < Quan; i++) { Pst = Geos2D_Intersection.Intersection_L2C(AxisX, WBs[i]); if (Pst.Count == 0) { continue; } P = Pst[0]; Array.Resize <WPoint2D>(ref Ps, N + 1); Array.Resize <int>(ref Ns, N + 1); Ps[N] = P; Ns[N] = i; N++; } ///////得到竖向线并排序输出 int[] Sort = WMFuncs2D.Ps_Sort(ref Ps, true, true); WEntity2D[] Out = new WEntity2D[N]; for (int i = 0; i < N; i++) { Out[i] = WBs[Ns[Sort[i]]]; } ///////去除竖向线 for (int i = 0; i < N; i++) { for (int j = 0; j < WBs.Length; j++) { if (Ns[i] == j) { for (int k = j; k < WBs.Length - 1; k++) { WBs[k] = WBs[k + 1]; } Array.Resize <WEntity2D>(ref WBs, WBs.Length - 1); for (int k = i + 1; k < N; k++) { Ns[k] = Ns[k] - 1; } break; } } } return(Out); }
private static bool Near_Check(WPoint2D P1, WPoint2D P2) { if (Math.Abs(P1.X - P2.X) < WGeos2D_Paras.E_Merge && Math.Abs(P1.Y - P2.Y) < WGeos2D_Paras.E_Merge) { return(true); } else { return(false); } }
/// <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> /// 判断两点是否是同一点 /// </summary> /// <param name="P1"></param> /// <param name="P2"></param> /// <returns></returns> public static bool Near_Check(WPoint2D P1, WNode2D P2) { if ((Math.Abs(P1.X - P2.X) < WGeos2D_Paras.E_Merge) && (Math.Abs(P1.Y - P2.Y) < WGeos2D_Paras.E_Merge)) { return(true); } else { return(false); } }
/// 寻找某个已有节点编号,不存在则 private static int Get_NodeNum(WPoint2D P, WMesh2D_Mesh Mesh, ref int N) { for (int j = 1; j < Mesh.Nodes.Count; j++) { if (WMFuncs2D.Near_Check(P, Mesh.Nodes[j]) == true) { return(j); } } N++; Mesh.Add_N(P, N); return(N); }
public static double ClosestDistance_P2C(WEntity2D E, WPoint2D P, bool Extent) { if (E.Kind == GeoKind.Line) { WLine2D L = (WLine2D)E; return(ClosestDistance_P2L(L.StartPoint, L.EndPoint, P, Extent)); } else { WPolyLine2D PL = (WPolyLine2D)E; return(ClosestDistance_P2PL(P, PL, Extent)); } }
public static List <WPoint2D> DotCurve_Times(WEntity2D C, WPoint2D P1, WPoint2D P2, int Times, ref WGeometry2D WGC) { if (Times == 0 || Times == 1) { List <WPoint2D> Out = new List <WPoint2D>(); Out.Add(((WCurve2D)C).StartPoint); Out.Add(((WCurve2D)C).EndPoint); return(Out); } if (C.Kind == GeoKind.Line) { return(Dotline_Times((WLine2D)C, P1, P2, Times)); } return(DotPolyline_Times((WPolyLine2D)C, P1, P2, Times, ref WGC)); }
/// 找到某点所在的Bnd的编号 private static List <int> Bnd_Find(WPoint2D P, ref WCurve2D[] Bnds) { List <int> Out = new List <int>(); double Dt; for (int i = 0; i < Bnds.Length; i++) { Dt = Geos2D_Other.ClosestDistance_P2C(Bnds[i], P, true); if (Dt < WGeos2D_Paras.E_Merge) { Out.Add(i); } } return(Out); }
/// <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); } }
/// 判断点的Range区域内是否有其他点 /// <summary> /// 判断点的Range区域内是否有其他点 /// </summary> public List <int> Point_Check(WPoint2D P, double Range) { int[] Xts = Search_Coord_Range(P.X - Range, P.X + Range, ref Xs); int[] Yts = Search_Coord_Range(P.Y - Range, P.Y + Range, ref Ys); int[] XIs = new int[Xts[1] - Xts[0] + 1]; int[] YIs = new int[Yts[1] - Yts[0] + 1]; for (int i = 0; i <= (Xts[1] - Xts[0]); i++) { XIs[i] = XsIndexs[Xts[0] + i]; } for (int i = 0; i <= (Yts[1] - Yts[0]); i++) { YIs[i] = YsIndexs[Yts[0] + i]; } return(Index_Inter(ref XIs, ref YIs)); }
private static void Read_PolyLine(ref StreamReader sr, ref WGeometry2D WGC) { tLayer = sr.ReadLine(); t_1 = sr.ReadLine().Split(','); tColor = Color.FromArgb(Convert.ToInt16(t_1[0]), Convert.ToInt16(t_1[1]), Convert.ToInt16(t_1[2])); tWidth = Convert.ToSingle(sr.ReadLine()); int Q = Convert.ToInt32(sr.ReadLine()); tPs = new List <WPoint2D>(); tPst = new WPoint2D[Q]; for (int i = 0; i < Q; i++) { t_1 = sr.ReadLine().Split(','); tPst[i] = new WPoint2D(Convert.ToDouble(t_1[0]), Convert.ToDouble(t_1[1])); } tPs.Add(WGC.PsList.Add(tPst[0].X, tPst[0].Y, true)); for (int i = 1; i < Q - 1; i++) { if (Near_Check(tPst[i], tPst[i - 1]) == false && Near_Check(tPst[i], tPst[i + 1]) == false) { tPs.Add(WGC.PsList.Add(tPst[i].X, tPst[i].Y, false)); } } tPs.Add(WGC.PsList.Add(tPst[Q - 1].X, tPst[Q - 1].Y, true)); tPst = null; ///// if (tPs.Count < 2) { sr.ReadLine(); return; } WPolyLine2D PL = new WPolyLine2D(tPs, ref WGC); PL.Kind = GeoKind.PolyLine; PL.Layer = tLayer; PL.Color = tColor; PL.LineWidth = tWidth; PL.Sort = ShowSort._5; WGC.Add_Geo(PL); sr.ReadLine(); }
/// <summary> /// 拾取2D几何曲线 /// </summary> /// <param name="P"></param> /// <param name="data"></param> private void Snap_Geo2DEntity(WPoint2D P, RenderData data) { Geo2D_Entities.Clear(); Geo2D_Temp.Clear(); try { if (data.Entities.Count == 0 || data.Entities == null) { return; } } catch { } /////// for (int i = 0; i < data.Entities.Count; i++) { if (!(data.Entities[i] is WCurve2D)) { continue; } if (((WCurve2D)data.Entities[i]).Contains(P, 2f) == true) { Geo2D_Temp.Add(i); } } if (Geo2D_Temp.Count == 0) { return; } ///// NumMin = Geo2D_Temp[0]; DisMin = double.MaxValue; Diss = new double[Geo2D_Temp.Count]; for (int i = 0; i < Geo2D_Temp.Count; i++) { Dis = ((WCurve2D)(data.Entities[Geo2D_Temp[i]])).GetDistance(P); Diss[i] = Dis; if (Dis < DisMin) { DisMin = Dis; NumMin = Geo2D_Temp[i]; } } Geo2D_Entities.Add(NumMin); }
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> /// 判断一个点是否在Rim内部 /// </summary> /// <param name="Rim"></param> /// <param name="P"></param> /// <returns></returns> private bool Check_PointInside(WRim2D Rim, WPoint2D P) { int polySides = Rim.Shape.Count; int j = polySides - 1; bool oddNodes = false; for (int i = 0; i < polySides; i++) { if ((Rim.Shape[i].Y < P.Y && Rim.Shape[j].Y >= P.Y || Rim.Shape[j].Y < P.Y && Rim.Shape[i].Y >= P.Y) && (Rim.Shape[i].X <= P.X || Rim.Shape[j].X <= P.X)) { oddNodes ^= (Rim.Shape[i].X + (P.Y - Rim.Shape[i].Y) / (Rim.Shape[j].Y - Rim.Shape[i].Y) * (Rim.Shape[j].X - Rim.Shape[i].X) < P.X); } j = i; } return(oddNodes); }
/// <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); }
public void Snap(RenderData data, WPoint2D P, List <SnapMode> Modes) { if (data == null) { Geo2D_Entities.Clear(); return; } if (Modes.Contains(SnapMode.Geo2DEntity)) { Snap_Geo2DEntity(P, data); } if (Modes.Contains(SnapMode.Geo2DRim)) { Snap_Geo2DRim(P, data); } if (Modes.Contains(SnapMode.Geo2DPoint)) { Snap_Geo2DPoint(P, data); } }
private static bool CheckBound_Double(WLine2D L, WPoint2D P1, WPoint2D P2) { if (P1.X > L.StartPoint.X && P1.X > L.EndPoint.X && P2.X > L.StartPoint.X && P2.X > L.EndPoint.X) { return(false); } if (P1.X < L.StartPoint.X && P1.X < L.EndPoint.X && P2.X < L.StartPoint.X && P2.X < L.EndPoint.X) { return(false); } if (P1.Y > L.StartPoint.Y && P1.Y > L.EndPoint.Y && P2.Y > L.StartPoint.Y && P2.Y > L.EndPoint.Y) { return(false); } if (P1.Y < L.StartPoint.Y && P1.Y < L.EndPoint.Y && P2.Y < L.StartPoint.Y && P2.Y < L.EndPoint.Y) { return(false); } return(true); }
private static bool CheckBound_Single(WLine2D L, WPoint2D P) { if (P.X < L.StartPoint.X && P.X < L.EndPoint.X) { return(false); } if (P.X > L.StartPoint.X && P.X > L.EndPoint.X) { return(false); } if (P.Y < L.StartPoint.Y && P.Y < L.EndPoint.Y) { return(false); } if (P.Y > L.StartPoint.Y && P.Y > L.EndPoint.Y) { return(false); } return(true); }
private static List <WPoint2D> DotPolyline_Times(WPolyLine2D PL, WPoint2D P1, WPoint2D P2, int Times, ref WGeometry2D WGC) { ///求取最近点 WPoint2D p1 = (WPoint2D)Geos2D_Other.ClosestPoint_P2PL(P1, PL, true); WPoint2D p2 = (WPoint2D)Geos2D_Other.ClosestPoint_P2PL(P2, PL, true); if (p1.CheckNum > p2.CheckNum) ///如果p2排在p1之前,需要对换位置 { WPoint2D p = p1; p1 = p2; p2 = p; } List <WPoint2D> Ps = new List <WPoint2D>(); Ps.Add(p1); for (int i = p1.CheckNum + 1; i <= p2.CheckNum; i++) { Ps.Add(PL[i]); } Ps.Add(p2); WPolyLine2D PL2 = new WPolyLine2D(Ps, ref WGC); return(DotPolyline_Times(PL2, Times)); }
/// <summary> /// 在世界中加入线的编号 /// </summary> /// <param name="Curves"></param> /// <param name="WGC"></param> private static void Add_CurveNum(ref WEntity2D[] Curves, ref WGeometry2D WGC) { string N; WPoint2D S, E; int A; WPoint2D P = new WPoint2D(); for (int i = 0; i < Curves.Length; i++) { N = Convert.ToString(i); if (Curves[i].Kind == GeoKind.Line) { S = ((WCurve2D)Curves[i]).StartPoint; E = ((WCurve2D)Curves[i]).EndPoint; P = new WPoint2D((S.X + E.X) / 2, (S.Y + E.Y) / 2); } if (Curves[i].Kind == GeoKind.PolyLine) { A = ((WPolyLine2D)Curves[i]).Count / 2; P = ((WPolyLine2D)Curves[i])[A]; } WGC.Add_Geo(new WText2D(N, P, 10)); } }