Exemple #1
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);
        }
Exemple #2
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);
        }
Exemple #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;
        }
Exemple #4
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);
        }