Example #1
0
        /// <summary>
        /// Adds the other to this if there is a common end i.e. they can be joined up.
        /// </summary>
        /// <param name="Other">Input. The other set.</param>
        public bool AddIfCommonEnd(C2DLineBaseSet Other)
        {
            Debug.Assert(!IsClosed(true));
            Debug.Assert(!Other.IsClosed(true));

            var nThisCount = Count;

            if (nThisCount < 1)
            {
                return(false);
            }

            var nOtherCount = Other.Count;

            if (nOtherCount < 1)
            {
                return(false);
            }

            if (this[0].GetPointFrom().PointEqualTo(Other[0].GetPointFrom()))
            {
                ReverseDirection();

                this.ExtractAllOf(Other);

                return(true);
            }
            else if (this[0].GetPointFrom().PointEqualTo(Other[nOtherCount - 1].GetPointTo()))
            {
                ReverseDirection();

                Other.ReverseDirection();

                this.ExtractAllOf(Other);

                return(true);
            }
            else if (this[nThisCount - 1].GetPointTo().PointEqualTo(Other[0].GetPointFrom()))
            {
                this.ExtractAllOf(Other);

                return(true);
            }
            else if (this[nThisCount - 1].GetPointTo().PointEqualTo(Other[nOtherCount - 1].GetPointTo()))
            {
                Other.ReverseDirection();

                this.ExtractAllOf(Other);

                return(true);
            }

            return(false);
        }
Example #2
0
        /// <summary>
        /// Returns the boolean result (e.g. union) of 2 shapes. Boolean Operation defined by
        /// the inside / outside flags.
        /// </summary>
        /// <param name="Other">Other polygon.</param>
        /// <param name="HoledPolys">Set of polygons to recieve the result.</param>
        /// <param name="bThisInside">Does the operation require elements of this INSIDE the other.</param>
        /// <param name="bOtherInside">Does the operation require elements of the other INSIDE this.</param>
        /// <param name="grid">The grid with the degenerate settings.</param>
        public void GetBoolean(C2DHoledPolyBase Other, List <C2DHoledPolyBase> HoledPolys,
                               bool bThisInside, bool bOtherInside,
                               CGrid grid)
        {
            if (_Rim.Lines.Count == 0 || Other.Rim.Lines.Count == 0)
            {
                return;
            }

            if (_Rim.BoundingRect.Overlaps(Other.Rim.BoundingRect))
            {
                switch (grid.DegenerateHandling)
                {
                case CGrid.eDegenerateHandling.None:
                {
                    var CompleteHoles1 = new List <C2DPolyBase>();
                    var CompleteHoles2 = new List <C2DPolyBase>();
                    var Routes1        = new C2DLineBaseSetSet();
                    var Routes2        = new C2DLineBaseSetSet();
                    GetRoutes(this, bThisInside, Other, bOtherInside, Routes1, Routes2,
                              CompleteHoles1, CompleteHoles2, grid);

                    Routes1.ExtractAllOf(Routes2);

                    if (Routes1.Count > 0)
                    {
                        Routes1.MergeJoining();

                        var Polygons = new List <C2DPolyBase>();

                        for (var i = Routes1.Count - 1; i >= 0; i--)
                        {
                            C2DLineBaseSet pRoute = Routes1[i];
                            if (pRoute.IsClosed(true))
                            {
                                Polygons.Add(new C2DPolyBase());
                                Polygons[Polygons.Count - 1].CreateDirect(pRoute);
                            }
                            else
                            {
                                //   Debug.Assert(false);
                                grid.LogDegenerateError();
                            }
                        }

                        var NewComPolys = new C2DHoledPolyBaseSet();

                        PolygonsToHoledPolygons(NewComPolys, Polygons);

                        NewComPolys.AddKnownHoles(CompleteHoles1);

                        NewComPolys.AddKnownHoles(CompleteHoles2);

                        if (!bThisInside && !bOtherInside && NewComPolys.Count != 1)
                        {
                            //  Debug.Assert(false);
                            grid.LogDegenerateError();
                        }


                        HoledPolys.AddRange(NewComPolys);

                        NewComPolys.Clear();
                    }
                }
                break;

                case CGrid.eDegenerateHandling.RandomPerturbation:
                {
                    var OtherCopy = new C2DHoledPolyBase(Other);
                    OtherCopy.RandomPerturb();
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    GetBoolean(OtherCopy, HoledPolys, bThisInside, bOtherInside, grid);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.RandomPerturbation;
                }
                break;

                case CGrid.eDegenerateHandling.DynamicGrid:
                {
                    var Rect = new C2DRect();
                    if (_Rim.BoundingRect.Overlaps(Other.Rim.BoundingRect, Rect))
                    {
                        //double dOldGrid = CGrid::GetGridSize();
                        grid.SetToMinGridSize(Rect, false);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
                        GetBoolean(Other, HoledPolys, bThisInside, bOtherInside, grid);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.DynamicGrid;
                    }
                }
                break;

                case CGrid.eDegenerateHandling.PreDefinedGrid:
                {
                    var P1 = new C2DHoledPolyBase(this);
                    var P2 = new C2DHoledPolyBase(Other);
                    P1.SnapToGrid(grid);
                    P2.SnapToGrid(grid);
                    var V1            = new C2DVector(P1.Rim.BoundingRect.TopLeft, P2.Rim.BoundingRect.TopLeft);
                    var dPerturbation = grid.GridSize;                     // ensure it snaps back to original grid positions.
                    if (V1.i > 0)
                    {
                        V1.i = dPerturbation;
                    }
                    else
                    {
                        V1.i = -dPerturbation;          // move away slightly if possible
                    }
                    if (V1.j > 0)
                    {
                        V1.j = dPerturbation;
                    }
                    else
                    {
                        V1.j = -dPerturbation;     // move away slightly if possible
                    }
                    V1.i *= 0.411923;              // ensure it snaps back to original grid positions.
                    V1.j *= 0.313131;              // ensure it snaps back to original grid positions.

                    P2.Move(V1);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    P1.GetBoolean(P2, HoledPolys, bThisInside, bOtherInside, grid);

                    for (var i = 0; i < HoledPolys.Count; i++)
                    {
                        HoledPolys[i].SnapToGrid(grid);
                    }

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
                }
                break;

                case CGrid.eDegenerateHandling.PreDefinedGridPreSnapped:
                {
                    var P2            = new C2DHoledPolyBase(Other);
                    var V1            = new C2DVector(_Rim.BoundingRect.TopLeft, P2.Rim.BoundingRect.TopLeft);
                    var dPerturbation = grid.GridSize;
                    if (V1.i > 0)
                    {
                        V1.i = dPerturbation;
                    }
                    else
                    {
                        V1.i = -dPerturbation;     // move away slightly if possible
                    }
                    if (V1.j > 0)
                    {
                        V1.j = dPerturbation;
                    }
                    else
                    {
                        V1.j = -dPerturbation;     // move away slightly if possible
                    }
                    V1.i *= 0.411923;              // ensure it snaps back to original grid positions.
                    V1.j *= 0.313131;              // ensure it snaps back to original grid positions.
                    P2.Move(V1);

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    GetBoolean(P2, HoledPolys, bThisInside, bOtherInside, grid);

                    for (var i = 0; i < HoledPolys.Count; i++)
                    {
                        HoledPolys[i].SnapToGrid(grid);
                    }

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGridPreSnapped;
                }
                break;
                }        // switch
            }
        }