private static int FindNextClosest(List <PathDefWithClosed> Paths) { QuadTreeNode Root = new QuadTreeNode(); PolyLineSet.Bounds B = new PolyLineSet.Bounds(); for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { B.FitPoint(Paths[i].Vertices.First()); B.FitPoint(Paths[i].Vertices.Last()); } } Root.xstart = B.TopLeft.X - 10; Root.xend = B.BottomRight.X + 10; Root.ystart = B.TopLeft.Y - 10; Root.yend = B.BottomRight.Y + 10; for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Vertices.First(), Side = SideEnum.Start }, 5); Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Vertices.Last(), Side = SideEnum.End }, 5); } } RectangleF R = new RectangleF(); R.Width = 3; R.Height = 3; for (int i = 0; i < Paths.Count; i++) { var P = Paths[i]; if (P.Closed == false) { var PF = P.Vertices[0]; var PF2 = P.Vertices[1]; var PathDir = PF - PF2;// MathHelpers.Difference(PF, PF2); PathDir.Normalize(); R.X = (float)(P.Vertices.First().X - 1.5); R.Y = (float)(P.Vertices.First().Y - 1.5); int startmatch = -1; int endmatch = -1; double closestdistance = B.Width() + B.Height(); Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } if (P.Width != Paths[S.PathID].Width) { return(true); } PointD Dir2; if (S.Side == SideEnum.Start) { var S2 = Paths[S.PathID].Vertices[1]; Dir2 = S2 - S.Point; Dir2.Normalize(); } else { var S2 = Paths[S.PathID].Vertices[Paths[S.PathID].Vertices.Count() - 2]; Dir2 = S2 - S.Point; Dir2.Normalize(); } double dotted = Dir2.Dot(PathDir); var D = PointD.Distance(S.Point, PF); if (D < 1.0) { // D -= dotted * 3.0; if (D < closestdistance) { closestdistance = D; if (S.Side == SideEnum.Start) { startmatch = S.PathID; } else { endmatch = S.PathID; } } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { if (closestdistance > 0) { Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last()); } Paths[endmatch].Vertices.AddRange(Paths[i].Vertices); if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 4a", Paths[endmatch].Vertices.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); // Console.WriteLine(" 4a"); return(1); } if (startmatch > -1) { Paths[i].Vertices.Reverse(); if (closestdistance > 0) { Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); } Paths[i].Vertices.AddRange(Paths[startmatch].Vertices); if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 4b", Paths[i].Vertices.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); //Console.WriteLine(" 4b"); return(1); } } PF = P.Vertices.Last(); R.X = (float)(P.Vertices.First().X - 1.5); R.Y = (float)(P.Vertices.First().Y - 1.5); startmatch = -1; endmatch = -1; closestdistance = B.Width() + B.Height(); Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } if (P.Width != Paths[S.PathID].Width) { return(true); } var D = PointD.Distance(S.Point, PF); if (D < 1.0 && D < closestdistance) { closestdistance = D; if (S.Side == SideEnum.Start) { startmatch = S.PathID; } else { endmatch = S.PathID; } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { Paths[i].Vertices.Reverse(); if (closestdistance > 0) { Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last()); } Paths[endmatch].Vertices.AddRange(Paths[i].Vertices); if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 4c", Paths[endmatch].Vertices.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); // Console.WriteLine(" 4c"); return(1); } if (startmatch > -1) { if (closestdistance > 0) { Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); } Paths[i].Vertices.AddRange(Paths[startmatch].Vertices); if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 4d", Paths[i].Vertices.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); // Console.WriteLine(" 4d"); return(1); } } } } return(0); }
private static List <PathDefWithClosed> StripOverlaps(List <PathDefWithClosed> Paths) { List <PathDefWithClosed> Res = new List <PathDefWithClosed>(); QuadTreeNode Root = new QuadTreeNode(); PolyLineSet.Bounds B = new PolyLineSet.Bounds(); for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { foreach (var a in Paths[i].Vertices) { B.FitPoint(a); } } else { Res.Add(Paths[i]); } } Root.xstart = B.TopLeft.X - 10; Root.xend = B.BottomRight.X + 10; Root.ystart = B.TopLeft.Y - 10; Root.yend = B.BottomRight.Y + 10; RectangleF QueryRect = new RectangleF(); QueryRect.Width = 3; QueryRect.Height = 3; List <PathDefWithClosed> ToDelete = new List <PathDefWithClosed>(); for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { int nearcount = 0; foreach (var a in Paths[i].Vertices) { QueryRect.X = (float)a.X - 1.5f; QueryRect.Y = (float)a.Y - 1.5f; Root.CallBackInside(QueryRect, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.Point == a) { nearcount++; } else { if (PointD.Distance(a, S.Point) < 0.001) { nearcount++; } } return(true); } ); } int max = Math.Max(4, (Paths[i].Vertices.Count * 50) / 100); if (nearcount <= max) { foreach (var a in Paths[i].Vertices) { Root.Insert(new SegmentEndContainer() { PathID = i, Point = a, Side = SideEnum.Start }, 8); } Res.Add(Paths[i]); } else { Res.Add(Paths[i]); Console.WriteLine("{4}: {0} out of {1}/{2}/{3}", nearcount, max, Paths[i].Vertices.Count, (Paths[i].Vertices.Count * 90) / 100, i); Console.WriteLine("{0}: skipped!", i); } } } return(Res); }
private static int FindNextMerge(List <PathDefWithClosed> Paths, out int highestnomatch, int startat = 0) { highestnomatch = 0; QuadTreeNode Root = new QuadTreeNode(); PolyLineSet.Bounds B = new PolyLineSet.Bounds(); for (int i = startat; i < Paths.Count; i++) { if (Paths[i].Closed == false) { B.FitPoint(Paths[i].Vertices.First()); B.FitPoint(Paths[i].Vertices.Last()); } } Root.xstart = B.TopLeft.X - 10; Root.xend = B.BottomRight.X + 10; Root.ystart = B.TopLeft.Y - 10; Root.yend = B.BottomRight.Y + 10; for (int i = startat; i < Paths.Count; i++) { if (Paths[i].Closed == false) { Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Vertices.First(), Side = SideEnum.Start }, 4); Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Vertices.Last(), Side = SideEnum.End }, 4); } } RectangleF R = new RectangleF(); R.Width = 10; R.Height = 10; for (int i = startat; i < Paths.Count; i++) { // Console.WriteLine("checking path {0}", i); var P = Paths[i]; if (P.Closed == false) { var PF = P.Vertices.First(); // Console.WriteLine("checking firstvert {0}", PF); R.X = (float)(P.Vertices.First().X - 5); R.Y = (float)(P.Vertices.First().Y - 5); int startmatch = -1; int endmatch = -1; Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } // Console.WriteLine(" against {0}", S.Point); if (S.Point == PF) { if (S.Side == SideEnum.Start) { startmatch = S.PathID; // Console.WriteLine(" matched start {0}" , startmatch); } else { endmatch = S.PathID; // Console.WriteLine(" matched end {0}", endmatch); } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last()); Paths[endmatch].Vertices.AddRange(Paths[i].Vertices); if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 3a", Paths[endmatch].Vertices.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); //Console.WriteLine(" a"); return(1); } if (startmatch > -1) { Paths[i].Vertices.Reverse(); Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); Paths[i].Vertices.AddRange(Paths[startmatch].Vertices); if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 3b", Paths[i].Vertices.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); // Console.WriteLine(" b"); return(1); } } PF = P.Vertices.Last(); // Console.WriteLine("checking lastvert {0}", PF); R.X = (float)(P.Vertices.First().X - 5); R.Y = (float)(P.Vertices.First().Y - 5); startmatch = -1; endmatch = -1; Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } // Console.WriteLine(" against {0}", S.Point); if (S.Point == PF) { if (S.Side == SideEnum.Start) { startmatch = S.PathID; } else { endmatch = S.PathID; } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { Paths[i].Vertices.Reverse(); Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last()); Paths[endmatch].Vertices.AddRange(Paths[i].Vertices); if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 3c", Paths[endmatch].Vertices.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); //Console.WriteLine(" c"); return(1); } if (startmatch > -1) { Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); Paths[i].Vertices.AddRange(Paths[startmatch].Vertices); if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 3d", Paths[i].Vertices.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); //Console.WriteLine(" d"); return(1); } } highestnomatch = i; } } return(0); //for (int i = 0; i < Paths.Count; i++) //{ // for (int j = i + 1; j < Paths.Count; j++) // { // if (Paths[i].Closed == false && Paths[j].Closed == false) // { // if (Paths[j].Vertices.First() == Paths[i].Vertices.Last()) // { // Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); // Paths[i].Vertices.AddRange(Paths[j].Vertices); // if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) Paths[i].Closed = true; // Paths.Remove(Paths[j]); // return 1; // } // else // { // if (Paths[i].Vertices.First() == Paths[j].Vertices.Last()) // { // Paths[j].Vertices.Remove(Paths[j].Vertices.Last()); // Paths[j].Vertices.AddRange(Paths[i].Vertices); // if (Paths[j].Vertices.First() == Paths[j].Vertices.Last()) Paths[j].Closed = true; // Paths.Remove(Paths[i]); // return 1; // } // else // { // if (Paths[i].Vertices.First() == Paths[j].Vertices.First()) // { // Paths[i].Vertices.Reverse(); // Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); // Paths[i].Vertices.AddRange(Paths[j].Vertices); // if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) Paths[i].Closed = true; // Paths.Remove(Paths[j]); // return 1; // } // else // if (Paths[i].Vertices.Last() == Paths[j].Vertices.Last()) // { // Paths[i].Vertices.Reverse(); // Paths[j].Vertices.Remove(Paths[j].Vertices.Last()); // Paths[j].Vertices.AddRange(Paths[i].Vertices); // if (Paths[j].Vertices.First() == Paths[j].Vertices.Last()) Paths[j].Closed = true; // Paths.Remove(Paths[i]); // return 1; // } // } // } // } // } //} //return 0; }
private static int FindNextClosest(List <PathDefWithClosed> Paths) { QuadTreeNode Root = new QuadTreeNode(); Bounds B = new Bounds(); for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { B.FitPoint(Paths[i].Points.First()); B.FitPoint(Paths[i].Points.Last()); } } Root.xstart = B.TopLeft.X - 10; Root.xend = B.BottomRight.X + 10; Root.ystart = B.TopLeft.Y - 10; Root.yend = B.BottomRight.Y + 10; for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Points.First(), Side = SideEnum.Start }, 4); Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Points.Last(), Side = SideEnum.End }, 4); } } RectangleF R = new RectangleF(); R.Width = 30; R.Height = 30; for (int i = 0; i < Paths.Count; i++) { var P = Paths[i]; if (P.Closed == false) { var PF = P.Points.First(); R.X = (float)(P.Points.First().X - 15); R.Y = (float)(P.Points.First().Y - 15); int startmatch = -1; int endmatch = -1; double closestdistance = B.Width() + B.Height(); Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } var D = PointD.Distance(S.Point, PF); if (D < 1.0 && D < closestdistance) { closestdistance = D; if (S.Side == SideEnum.Start) { startmatch = S.PathID; } else { endmatch = S.PathID; } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { Paths[endmatch].Points.Remove(Paths[endmatch].Points.Last()); Paths[endmatch].Points.AddRange(Paths[i].Points); if (Paths[endmatch].Points.First() == Paths[endmatch].Points.Last()) { // Console.WriteLine("closed path with {0} points during stage 4a", Paths[endmatch].Points.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); // Console.WriteLine(" 4a"); return(1); } if (startmatch > -1) { Paths[i].Points.Reverse(); Paths[i].Points.Remove(Paths[i].Points.Last()); Paths[i].Points.AddRange(Paths[startmatch].Points); if (Paths[i].Points.First() == Paths[i].Points.Last()) { // Console.WriteLine("closed path with {0} points during stage 4b", Paths[i].Points.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); //Console.WriteLine(" 4b"); return(1); } } PF = P.Points.Last(); R.X = (float)(P.Points.First().X - 0.5); R.Y = (float)(P.Points.First().Y - 0.5); startmatch = -1; endmatch = -1; closestdistance = B.Width() + B.Height(); Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } var D = PointD.Distance(S.Point, PF); if (D < 1.0 && D < closestdistance) { closestdistance = D; if (S.Side == SideEnum.Start) { startmatch = S.PathID; } else { endmatch = S.PathID; } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { Paths[i].Points.Reverse(); Paths[endmatch].Points.Remove(Paths[endmatch].Points.Last()); Paths[endmatch].Points.AddRange(Paths[i].Points); if (Paths[endmatch].Points.First() == Paths[endmatch].Points.Last()) { // Console.WriteLine("closed path with {0} points during stage 4c", Paths[endmatch].Points.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); // Console.WriteLine(" 4c"); return(1); } if (startmatch > -1) { Paths[i].Points.Remove(Paths[i].Points.Last()); Paths[i].Points.AddRange(Paths[startmatch].Points); if (Paths[i].Points.First() == Paths[i].Points.Last()) { // Console.WriteLine("closed path with {0} points during stage 4d", Paths[i].Points.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); // Console.WriteLine(" 4d"); return(1); } } } } return(0); }