Example #1
0
        internal Tuple <double, PolyLine> FindLargestPolygon()
        {
            if (OutlineShapes.Count == 0)
            {
                return(null);
            }

            List <Tuple <double, PolyLine> > Polies = new List <Tuple <double, PolyLine> >();

            foreach (var a in OutlineShapes)
            {
                var area   = Core.Helpers.PolygonSurfaceArea(a.Vertices);
                var bounds = new PolyLineSet.Bounds();
                bounds.FitPoint(a.Vertices);
                Polies.Add(new Tuple <double, PolyLine>(bounds.Area(), a));
            }

            return((from a in Polies orderby a.Item1 descending select a).First());
        }
Example #2
0
        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);
        }
Example #3
0
        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;
        }
Example #4
0
        public static List <PathDefWithClosed> LineSegmentsToPolygons(List <PathDefWithClosed> input, bool joinclosest = true)
        {
            // return input;
            List <PathDefWithClosed> Paths         = new List <PathDefWithClosed>();
            List <PathDefWithClosed> FirstSweep    = new List <PathDefWithClosed>();
            List <PathDefWithClosed> LeftoverLines = new List <PathDefWithClosed>();

            if (input.Count == 0)
            {
                return(LeftoverLines);
            }
            try
            {
                foreach (var p in input)
                {
                    if (p.Vertices.Count() > 0)
                    {
                        FirstSweep.Add(Sanitize(p));
                    }
                }
                FirstSweep = StripOverlaps(FirstSweep);


                LeftoverLines.Add(FirstSweep[0]);
                for (int i = 1; i < FirstSweep.Count; i++)
                {
                    var LastLeft  = LeftoverLines.Last();
                    var LastLeftP = LastLeft.Vertices.Last();

                    if (FirstSweep[i].Vertices.First() == LastLeftP)
                    {
                        LastLeft.Vertices.AddRange(FirstSweep[i].Vertices.Skip(1));
                    }
                    else
                    {
                        if (FirstSweep[i].Vertices.Last() == LastLeftP)
                        {
                            FirstSweep[i].Vertices.Reverse();
                            LastLeft.Vertices.AddRange(FirstSweep[i].Vertices.Skip(1));
                        }
                        else
                        {
                            LeftoverLines.Add(FirstSweep[i]);
                        }
                    }
                }
                LeftoverLines = StripOverlaps(LeftoverLines);
            }
            catch (Exception E)
            {
                Console.WriteLine(E.Message);
            }

            while (LeftoverLines.Count > 0)
            {
                bool added = false;

                var a = LeftoverLines.Last();
                LeftoverLines.Remove(a);

                if (added == false)
                {
                    PathDefWithClosed P = new PathDefWithClosed();
                    P.Width = a.Width;

                    foreach (var v in a.Vertices)
                    {
                        P.Vertices.Add(v);
                    }
                    //P.Points.Add(a.Last());
                    if (a.Vertices.First() == a.Vertices.Last())
                    {
                        int matching = 0;
                        for (int i = 0; i < a.Vertices.Count / 2; i++)
                        {
                            if (a.Vertices[i] == a.Vertices[a.Vertices.Count - 1 - i])
                            {
                                matching++;
                            }
                        }
                        if (matching > 1)
                        {
                            P.Vertices.Clear();
                            List <PointD> DebugN  = new List <PointD>();
                            List <int>    Kinks   = new List <int>();
                            List <int>    KinkEnd = new List <int>();

                            Kinks.Add(0);
                            for (int i = 1; i < a.Vertices.Count; i++)
                            {
                                var N1 = MathHelpers.Normal(a.Vertices[(i - 1)], a.Vertices[i]);
                                var N2 = MathHelpers.Normal(a.Vertices[i], a.Vertices[(i + 1) % a.Vertices.Count()]);
                                if (N1.Dot(N2) < 0.8)
                                {
                                    DebugN.Add(a.Vertices[i]);
                                    DebugN.Add(N1 * 4.0 + a.Vertices[i]);
                                    Kinks.Add(i);
                                    KinkEnd.Add(i);
                                }
                            }
                            KinkEnd.Add(a.Vertices.Count - 1);

                            double maxD   = 0;
                            int    maxSeg = 0;
                            for (int i = 0; i < Kinks.Count; i++)
                            {
                                double D = 0;
                                for (int j = Kinks[i]; j < KinkEnd[i]; j++)
                                {
                                    D += (a.Vertices[j] - a.Vertices[j + 1]).Length();
                                }
                                if (D > maxD)
                                {
                                    maxD   = D;
                                    maxSeg = i;
                                }
                            }



                            for (int i = Kinks[maxSeg]; i < KinkEnd[maxSeg]; i++)
                            {
                                P.Vertices.Add(a.Vertices[i]);
                            }

                            bool dumpdebugline = false;
                            if (dumpdebugline)
                            {
                                PolyLineSet.Bounds Bbox = new PolyLineSet.Bounds();

                                foreach (var v in a.Vertices)
                                {
                                    Bbox.FitPoint(v);
                                    Bbox.FitPoint(new PointD(v.X + 10, v.Y + 10));
                                    Bbox.FitPoint(new PointD(v.X - 10, v.Y - 10));
                                }
                                float  Scaler = 50.0f;
                                Bitmap OutB   = new Bitmap((int)(Bbox.Width() * Scaler), (int)(Bbox.Height() * Scaler));

                                Graphics G = Graphics.FromImage(OutB);
                                G.Clear(Color.White);
                                GraphicsGraphicsInterface GGI = new GraphicsGraphicsInterface(G);

                                GGI.TranslateTransform((float)-Bbox.TopLeft.X * Scaler, (float)-Bbox.TopLeft.Y * Scaler);
                                GGI.DrawLines(new Pen(Color.Red, 0.1f), (from i in a.Vertices select(i * Scaler).ToF()).ToArray());
                                for (int i = 1; i < a.Vertices.Count; i++)
                                {
                                    var N = MathHelpers.Normal(a.Vertices[i - 1], a.Vertices[i]);

                                    GGI.DrawString(i.ToString(), new Font("arial", 14), new SolidBrush(Color.FromArgb((i + 128) % 256, i % 256, i % 256)), (float)a.Vertices[i].X * Scaler + (float)N.X * 20.0f, (float)a.Vertices[i].Y * Scaler + (float)N.Y * 20.0f, new StringFormat());
                                }
                                for (int i = 0; i < DebugN.Count; i += 2)
                                {
                                    GGI.DrawLine(new Pen(Color.DarkGreen, 1.0f), (DebugN[i] * Scaler).ToF(), (DebugN[i + 1] * Scaler).ToF());
                                }
                                OutB.Save("testout.png");
                            }
                        }
                        else
                        {
                            a.Vertices.Remove(a.Vertices.Last());
                            //Console.WriteLine("closed path with {0} points during stage 2: {1} reversematched", a.Vertices.Count(), matching);
                            P.Closed = true;
                        }
                    }
                    Paths.Add(P);
                }
            }
            Paths = StripOverlaps(Paths);
            //  return Paths;


            int Merges   = 1;
            int startat  = 0;
            int lasthigh = 0;

            while (Merges > 0)
            {
                startat = lasthigh;
                Merges  = FindNextMerge(Paths, out lasthigh, startat);
            }
            //return Paths;

            int ClosedCount = (from i in Paths where i.Closed == true select i).Count();

            if (ClosedCount < Paths.Count)
            {
                //Console.WriteLine("{0}/{1} paths open - finding closest connections", Paths.Count - ClosedCount, Paths.Count);
                if (joinclosest)
                {
                    Merges = 1;
                    while (Merges > 0)
                    {
                        Merges = FindNextClosest(Paths);
                    }

                    int NewClosedCount = (from i in Paths where i.Closed == true select i).Count();

                    Console.WriteLine("remaining open: {0}", NewClosedCount);

                    /*
                     * var OpenPaths = (from i in Paths where i.Closed == false select i).ToArray();
                     * //  foreach (var p in OpenPaths)
                     * //  {
                     * //     Paths.Remove(p);
                     * //  }
                     *
                     * while (OpenPaths.Count() > 1)
                     * {
                     *  var P = OpenPaths[0];
                     *  var V = P.Points.Last();
                     *  double ClosestDistance = 1000000;
                     *  int closestindex = 0;
                     *  bool forward = true;
                     *
                     *  double OwnDistance = (P.Points.First() - P.Points.Last()).Length();
                     *  ClosestDistance = OwnDistance;
                     *  for (int i = 1; i < OpenPaths.Count(); i++)
                     *  {
                     *      double dx1 = OpenPaths[i].Points.First().X - V.X;
                     *      double dy1 = OpenPaths[i].Points.First().Y - V.Y;
                     *
                     *      double dx2 = OpenPaths[i].Points.Last().X - V.X;
                     *      double dy2 = OpenPaths[i].Points.Last().Y - V.Y;
                     *
                     *      float disttofirst = (float)Math.Sqrt(dx1 * dx1 + dy1 * dy1);
                     *      float disttolast = (float)Math.Sqrt(dx2 * dx2 + dy2 * dy2);
                     *
                     *      if (disttofirst < ClosestDistance)
                     *      {
                     *          forward = true;
                     *          closestindex = i;
                     *          ClosestDistance = disttofirst;
                     *      }
                     *
                     *      if (disttolast < ClosestDistance)
                     *      {
                     *          forward = false;
                     *          closestindex = i;
                     *          ClosestDistance = disttolast;
                     *      }
                     *
                     *  }
                     *  if (OwnDistance == ClosestDistance)
                     *  {
                     *      P.Closed = true;
                     *      //      Paths.Add(P);
                     *  }
                     *  else
                     *  {
                     *      if (forward)
                     *      {
                     *          var PJ = OpenPaths[closestindex];
                     *          P.Points.AddRange(PJ.Points);
                     *          Paths.Remove(PJ);
                     *      }
                     *      else
                     *      {
                     *          var PJ = OpenPaths[closestindex];
                     *          PJ.Points.Reverse();
                     *          P.Points.AddRange(PJ.Points);
                     *          Paths.Remove(PJ);
                     *      }
                     *      if (P.Points.First() == P.Points.Last())
                     *      {
                     *          P.Closed = true;
                     *      }
                     *  }
                     *
                     *
                     *  OpenPaths = (from i in Paths where i.Closed == false select i).ToArray();
                     *
                     * }*/
                }
            }
            List <PathDefWithClosed> Results = new List <PathDefWithClosed>();

            foreach (var p in Paths)
            {
                Results.Add(Sanitize(p));
            }
            return(Results);
        }
Example #5
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);
        }