コード例 #1
0
        /// <summary>
        /// Returns the list of polygons that are the sub-shapes of the minuends and that are not part of the subtrahends.
        /// Notice also that any overlap between the polygons in A or the polygons in B are ignored. Finally, all inputs must be positive.
        ///
        /// </summary>
        /// <param name="minuends">The polygons a.</param>
        /// <param name="subtrahends">The polygons b.</param>
        /// <param name="outputAsCollectionType">Type of the output as collection.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
        public static List <Polygon> Subtract(this IEnumerable <Polygon> minuends, IEnumerable <Polygon> subtrahends,
                                              PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles, double tolerance = double.NaN)
        {
            if (CLIPPER)
            {
                return(BooleanViaClipper(ClipperLib.PolyFillType.pftPositive, ClipperLib.ClipType.ctDifference, minuends,
                                         subtrahends));
            }
            var minuendsList    = minuends.ToList();
            var subtrahendsList = subtrahends as List <Polygon> ?? subtrahends.ToList();

            if (double.IsNaN(tolerance))
            {
                tolerance = GetTolerancesFromPolygons(minuendsList, subtrahendsList);
            }

            foreach (var polyB in subtrahendsList)
            {
                for (int i = minuendsList.Count - 1; i >= 0; i--)
                {
                    var newPolygons = minuendsList[i].Subtract(polyB, outputAsCollectionType, tolerance);
                    minuendsList.RemoveAt(i);
                    foreach (var newPoly in newPolygons)
                    {
                        minuendsList.Insert(i, newPoly);
                    }
                }
            }
            return(minuendsList);
        }
コード例 #2
0
        protected override async void OnAppearing()
        {
            base.OnAppearing();
            try
            {
                var position = await Utilities.GetCurrentGeolocationAsync();

                MyPosition = new Position(position.Latitude, position.Longitude);
                PinCollection.Add(new CustomPin()
                {
                    Id       = "Ryan",
                    Position = MyPosition,
                    Label    = "Ryan",
                    Type     = PinType.Generic,
                    Url      = "http://www.ryanrauch.com/"
                });

                PolygonCollection.Add(new Position(30.39983, -97.723719));
                PolygonCollection.Add(new Position(30.40182, -97.722989));
                PolygonCollection.Add(new Position(30.402172, -97.724245));
                PolygonCollection.Add(new Position(30.403236, -97.72374));
                PolygonCollection.Add(new Position(30.402606, -97.721659));
                PolygonCollection.Add(new Position(30.399562, -97.723011));

                //UpdateMapGrid();
                //UpdateLocation();
                //UpdatePolygons();
                //MapContent.PropertyChanged += MapContent_PropertyChanged; //this has not worked yet, but used to change grids when zoomed by user
                //UpdateRestService();
            }
            catch (Exception ex)
            {
                await DisplayAlert(ex.Message, ex.StackTrace, "OK");
            }
        }
コード例 #3
0
        /*public async void UpdateRestService()
         * {
         *  try
         *  {
         *      RestService svc = new RestService();
         *      var regions = await svc.GetRegionsAsync();
         *      await DisplayAlert(regions.Count.ToString(), "regions count", "OK");
         *  }
         *  catch (Exception ex)
         *  {
         *      await DisplayAlert(ex.Message, ex.StackTrace, "OK");
         *  }
         * }*/

        public void UpdatePolygons()
        {
            //ObservableCollection<Position> rockrose = new ObservableCollection<Position>();
            PolygonCollection.Add(new Position(30.39983, -97.723719));
            PolygonCollection.Add(new Position(30.40182, -97.722989));
            PolygonCollection.Add(new Position(30.402172, -97.724245));
            PolygonCollection.Add(new Position(30.403236, -97.72374));
            PolygonCollection.Add(new Position(30.402606, -97.721659));
            PolygonCollection.Add(new Position(30.399562, -97.723011));
            //6 original coordinates

            /*
             * // Intersection removing an interior polygon
             * PolygonCollection.Add(new Position(30.401807, -97.722484));
             * PolygonCollection.Add(new Position(30.402455, -97.722248));
             * PolygonCollection.Add(new Position(30.402561, -97.722623));
             * PolygonCollection.Add(new Position(30.402302, -97.722784));
             */
            //TODO: look into xamarin and mvvmlight
            //also look into collectionchanged event??


            //OnPropertyChanged("PolygonCollection");
            //PolygonCollection = rockrose;
        }
コード例 #4
0
        private static IMultiPolygon FlattenMultiPolygon(IMultiPolygon mpoly, FgfGeometryFactory factory)
        {
            PolygonCollection polys = new PolygonCollection();

            for (int i = 0; i < mpoly.Count; i++)
            {
                polys.Add(FlattenPolygon(mpoly[i], factory));
            }
            return(factory.CreateMultiPolygon(polys));
        }
コード例 #5
0
        /// <summary>
        /// Returns the list of polygons that are the Exclusive-OR of the two input polygons. Exclusive-OR are the regions where one polgyon
        /// resides but not both.
        /// </summary>
        /// <param name="polygonA">The polygon a.</param>
        /// <param name="polygonB">The polygon b.</param>
        /// <param name="outputAsCollectionType">Type of the output as collection.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
        public static List <Polygon> ExclusiveOr(this Polygon polygonA, Polygon polygonB,
                                                 PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles, double tolerance = double.NaN)
        {
            if (CLIPPER)
            {
                return(BooleanViaClipper(ClipperLib.PolyFillType.pftPositive, ClipperLib.ClipType.ctXor, new[] { polygonA },
                                         new[] { polygonB }));
            }
            var relationship = GetPolygonInteraction(polygonA, polygonB, tolerance);

            return(ExclusiveOr(polygonA, polygonB, relationship, outputAsCollectionType, tolerance));
        }
コード例 #6
0
        /// <summary>
        /// Returns the list of polygons that result from A-B (subtracting polygon B from polygon A).
        /// </summary>
        /// <param name="minuend">The polygon a.</param>
        /// <param name="subtrahend">The polygon b.</param>
        /// <param name="outputAsCollectionType">Type of the output as collection.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
        public static List <Polygon> Subtract(this Polygon minuend, Polygon subtrahend,
                                              PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles, double tolerance = double.NaN)
        {
            if (CLIPPER)
            {
                return(BooleanViaClipper(ClipperLib.PolyFillType.pftPositive, ClipperLib.ClipType.ctDifference, new[] { minuend },
                                         new[] { subtrahend }));
            }
            var polygonBInverted = subtrahend.Copy(true, true);
            var relationship     = GetPolygonInteraction(minuend, polygonBInverted, tolerance);

            return(Intersect(minuend, polygonBInverted, relationship, outputAsCollectionType, tolerance));
        }
コード例 #7
0
        // コンストラクター
        public LineGroupCollection(Field parent, Color color, PolygonCollection polygons)
        {
            this.Parent = parent;
            this.Color  = color;

            // 多角形を作成する。
            this.items =
                Enumerable
                .Range(0, polygons.Count)
                .Reverse()
                .Select(idx => new LineGroup(this, polygons[idx], this.GetTransparency(idx, polygons.Count)))
                .Reverse()
                .ToArray();
        }
コード例 #8
0
ファイル: FormExample4.cs プロジェクト: nromik/sharpgl
        private void buttonLoad_Click_1(object sender, EventArgs e)
        {
            //  Create a Persistence Engine.
            SharpGL.Persistence.PersistenceEngine engine = new SharpGL.Persistence.PersistenceEngine();

            //  Create a a set of polygons.
            PolygonCollection loaded = (PolygonCollection)engine.UserLoad(typeof(PolygonCollection));

            //  If we successfully loaded, set the collection.
            if (loaded != null)
            {
                polygons = loaded;
                foreach(Polygon polygon in loaded)
                    polygon.Attributes.PolygonDrawMode = SharpGL.SceneGraph.Attributes.Polygon.PolygonMode.Lines;
            }
        }
コード例 #9
0
ファイル: MapViewModel.cs プロジェクト: ryanrauch/ApproxiMATE
        public void UpdatePolygons()
        {
            //ObservableCollection<Position> rockrose = new ObservableCollection<Position>();
            PolygonCollection.Add(new Position(30.39983, -97.723719));
            PolygonCollection.Add(new Position(30.40182, -97.722989));
            PolygonCollection.Add(new Position(30.402172, -97.724245));
            PolygonCollection.Add(new Position(30.403236, -97.72374));
            PolygonCollection.Add(new Position(30.402606, -97.721659));
            PolygonCollection.Add(new Position(30.399562, -97.723011));

            //TODO: look into xamarin and mvvmlight
            //also look into collectionchanged event??


            //OnPropertyChanged("PolygonCollection");
            //PolygonCollection = rockrose;
        }
コード例 #10
0
        private void buttonLoad_Click_1(object sender, EventArgs e)
        {
            //  Create a Persistence Engine.
            SharpGL.Persistence.PersistenceEngine engine = new SharpGL.Persistence.PersistenceEngine();

            //  Create a a set of polygons.
            PolygonCollection loaded = (PolygonCollection)engine.UserLoad(typeof(PolygonCollection));

            //  If we successfully loaded, set the collection.
            if (loaded != null)
            {
                polygons = loaded;
                foreach (Polygon polygon in loaded)
                {
                    polygon.Attributes.PolygonDrawMode = SharpGL.SceneGraph.Attributes.Polygon.PolygonMode.Lines;
                }
            }
        }
コード例 #11
0
 /// <summary>
 /// Returns the list of polygons that result from the subshapes common to both A and B. By providing the intersections
 /// between the two polygons, the operation will be performed with less time and memory.
 /// </summary>
 /// <param name="polygonA">The polygon a.</param>
 /// <param name="polygonB">The polygon b.</param>
 /// <param name="interaction">The interaction.</param>
 /// <param name="outputAsCollectionType">Type of the output as collection.</param>
 /// <param name="tolerance">The minimum allowable area.</param>
 /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
 public static List <Polygon> Intersect(this Polygon polygonA, Polygon polygonB, PolygonInteractionRecord interaction,
                                        PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles, double tolerance = double.NaN)
 {
     if (interaction.IntersectionWillBeEmpty())
     {
         if (polygonB.IsPositive)
         {
             return(new List <Polygon>());
         }
         else
         {
             return new List <Polygon> {
                        polygonA.Copy(true, false)
             }
         };
     }
     else
     {
         polygonIntersection ??= new PolygonIntersection();
         return(polygonIntersection.Run(polygonA, polygonB, interaction, outputAsCollectionType, tolerance));
     }
 }
コード例 #12
0
 /// <summary>
 /// Returns the list of polygons that exist in either A OR B.By providing the intersections
 /// between the two polygons, the operation will be performed with less time and memory.
 /// </summary>
 /// <param name="polygonA">The polygon a.</param>
 /// <param name="polygonB">The polygon b.</param>
 /// <param name="polygonInteraction">The polygon relationship.</param>
 /// <param name="outputAsCollectionType">Type of the output as collection.</param>
 /// <param name="tolerance">The minimum allowable area.</param>
 /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
 /// <exception cref="ArgumentException">A negative polygon (i.e. hole) is provided to Union which results in infinite shape. - polygonA</exception>
 /// <exception cref="ArgumentException">A negative polygon (i.e. hole) is provided to Union which results in infinite shape. - polygonB</exception>
 public static List <Polygon> Union(this Polygon polygonA, Polygon polygonB, PolygonInteractionRecord polygonInteraction,
                                    PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles, double tolerance = double.NaN)
 {
     if (!polygonA.IsPositive)
     {
         throw new ArgumentException("A negative polygon (i.e. hole) is provided to Union which results in infinite shape.", nameof(polygonA));
     }
     if (!polygonB.IsPositive)
     {
         throw new ArgumentException("A negative polygon (i.e. hole) is provided to Union which results in infinite shape.", nameof(polygonB));
     }
     if (!polygonInteraction.CoincidentEdges && (polygonInteraction.Relationship == PolygonRelationship.Separated ||
                                                 polygonInteraction.Relationship == PolygonRelationship.AIsInsideHoleOfB ||
                                                 polygonInteraction.Relationship == PolygonRelationship.BIsInsideHoleOfA))
     {
         return new List <Polygon> {
                    polygonA.Copy(true, false), polygonB.Copy(true, false)
         }
     }
     ;
     if (polygonInteraction.Relationship == PolygonRelationship.BInsideA ||
         polygonInteraction.Relationship == PolygonRelationship.Equal)
     {
         return new List <Polygon> {
                    polygonA.Copy(true, false)
         }
     }
     ;
     if (polygonInteraction.Relationship == PolygonRelationship.AInsideB)
     {
         return new List <Polygon> {
                    polygonB.Copy(true, false)
         }
     }
     ;
     polygonUnion ??= new PolygonUnion();
     return(polygonUnion.Run(polygonA, polygonB, polygonInteraction, outputAsCollectionType, tolerance));
 }
コード例 #13
0
        /// <summary>
        /// Returns the list of polygons that are the Exclusive-OR of the two input polygons. Exclusive-OR are the regions where one polgyon
        /// resides but not both. By providing the intersections between the two polygons, the operation will be performed with less time and memory.
        /// </summary>
        /// <param name="polygonA">The polygon a.</param>
        /// <param name="polygonB">The polygon b.</param>
        /// <param name="interactionRecord">The interaction record.</param>
        /// <param name="outputAsCollectionType">Type of the output as collection.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
        public static List <Polygon> ExclusiveOr(this Polygon polygonA, Polygon polygonB, PolygonInteractionRecord interactionRecord,
                                                 PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles, double tolerance = double.NaN)
        {
            if (interactionRecord.IntersectionWillBeEmpty())
            {
                return new List <Polygon> {
                           polygonA.Copy(true, false), polygonB.Copy(true, false)
                }
            }
            ;
            else if (interactionRecord.Relationship == PolygonRelationship.BInsideA &&
                     !interactionRecord.CoincidentEdges && !interactionRecord.CoincidentVertices)
            {
                var polygonACopy1 = polygonA.Copy(true, false);

                polygonACopy1.AddInnerPolygon(polygonB.Copy(true, true));
                return(new List <Polygon> {
                    polygonACopy1
                });
            }
            else if (interactionRecord.Relationship == PolygonRelationship.AInsideB &&
                     !interactionRecord.CoincidentEdges && !interactionRecord.CoincidentVertices)
            {
                var polygonBCopy2 = polygonB.Copy(true, false);
                polygonBCopy2.AddInnerPolygon(polygonA.Copy(true, true));
                return(new List <Polygon> {
                    polygonBCopy2
                });
            }
            else
            {
                var result = polygonA.Subtract(polygonB, interactionRecord, outputAsCollectionType, tolerance);
                result.AddRange(polygonB.Subtract(polygonA, interactionRecord, outputAsCollectionType, tolerance));
                return(result);
            }
        }
コード例 #14
0
 private static IMultiPolygon FlattenMultiPolygon(IMultiPolygon mpoly, FgfGeometryFactory factory)
 {
     PolygonCollection polys = new PolygonCollection();
     for (int i = 0; i < mpoly.Count; i++)
     {
         polys.Add(FlattenPolygon(mpoly[i], factory));
     }
     return factory.CreateMultiPolygon(polys);
 }
コード例 #15
0
        /// <summary>
        /// All of the previous boolean operations are accomplished by this function. Note that the function RemoveSelfIntersections is also
        /// very simliar to this function.
        /// </summary>
        /// <param name="polygonA">The polygon a.</param>
        /// <param name="polygonB">The polygon b.</param>
        /// <param name="intersections">The intersections.</param>
        /// <param name="isSubtract">The switch direction.</param>
        /// <param name="crossProductSign">The cross product sign.</param>
        /// <param name="tolerance">The minimum allowable area.</param>
        /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
        internal List <Polygon> Run(Polygon polygonA, Polygon polygonB, PolygonInteractionRecord interaction, PolygonCollection polygonCollection,
                                    double tolerance = double.NaN)
        {
            double areaTolerance;

            if (double.IsNaN(tolerance))
            {
                var minDimension = Math.Min(polygonA.MaxX - polygonA.MinX, Math.Min(polygonA.MaxY - polygonA.MinY,
                                                                                    Math.Min(polygonB.MaxX - polygonB.MinX, polygonB.MaxY - polygonB.MinY)));
                tolerance     = Constants.BaseTolerance * minDimension;
                areaTolerance = tolerance * minDimension;
            }
            else
            {
                areaTolerance = tolerance * tolerance / Constants.BaseTolerance;    // why change the input tolerance? here, we are using it as a
            }
            // limit on the minimum allowable area only (about 12 lines down), so in order to change it from units of length to length-squared
            // we need to find the characteristic length that was multiplied by the base tolerance to obtain the linear tolerance.
            var delimiters = NumberVerticesAndGetPolygonVertexDelimiter(polygonA);

            delimiters = NumberVerticesAndGetPolygonVertexDelimiter(polygonB, delimiters[^ 1]);
コード例 #16
0
 /// <summary>
 /// Returns the list of polygons that result from A-B (subtracting polygon B from polygon A). By providing the intersections
 /// between the two polygons, the operation will be performed with less time and memory.
 /// </summary>
 /// <param name="minuend">The polygon a.</param>
 /// <param name="subtrahend">The polygon b.</param>
 /// <param name="interaction">The polygon relationship.</param>
 /// <param name="outputAsCollectionType">Type of the output as collection.</param>
 /// <param name="tolerance">The tolerance.</param>
 /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
 /// <exception cref="ArgumentException">The minuend is already a negative polygon (i.e. hole). Consider another operation"
 /// +" to accomplish this function, like Intersect. - polygonA</exception>
 public static List <Polygon> Subtract(this Polygon minuend, Polygon subtrahend, PolygonInteractionRecord interaction,
                                       PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles, double tolerance = double.NaN)
 {
     interaction = interaction.InvertPolygonInRecord(subtrahend, out var invertedPolygonB);
     return(Intersect(minuend, invertedPolygonB, interaction, outputAsCollectionType, tolerance));
 }
コード例 #17
0
        /// <summary>
        /// Returns the list of polygons that are the sub-shapes of ALL of the provided polygons. Notice this is called IntersectPolygons here
        /// to distinguish it from the LINQ function Intersect, which is also a valid extension for any IEnumerable collection.
        /// </summary>
        /// <param name="polygons">The polygons.</param>
        /// <param name="outputAsCollectionType">Type of the output as collection.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
        public static List <Polygon> IntersectPolygons(this IEnumerable <Polygon> polygons, PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles,
                                                       double tolerance = double.NaN)
        {
            if (CLIPPER)
            {
                return(BooleanViaClipper(ClipperLib.PolyFillType.pftPositive, ClipperLib.ClipType.ctIntersection, polygons));
            }
            var polygonList = polygons.ToList();

            for (int i = polygonList.Count - 2; i > 0; i--)
            {
                var clippingPoly = polygonList[i];
                polygonList.RemoveAt(i);
                for (int j = polygonList.Count - 1; j >= i; j--)
                {
                    var interaction = GetPolygonInteraction(clippingPoly, polygonList[j], tolerance);
                    if (interaction.IntersectionWillBeEmpty())
                    {
                        polygonList.RemoveAt(j);
                    }
                    else
                    {
                        var newPolygons = Intersect(clippingPoly, polygonList[j], interaction, outputAsCollectionType, tolerance);
                        foreach (var newPolygon in newPolygons)
                        {
                            polygonList.Insert(j, newPolygon);
                        }
                    }
                }
            }
            return(polygonList);
        }
コード例 #18
0
        /// <summary>
        /// Returns the list of polygons that are the sub-shapes of the two collections of polygons. Notice this is called IntersectPolygons here
        /// to distinguish it from the LINQ function Intersect, which is also a valid extension for any IEnumerable collection.
        /// Notice also that any overlap between the polygons in A or the polygons in B are ignored. Finally, all inputs must be positive.
        ///
        /// </summary>
        /// <param name="polygonsA">The polygons a.</param>
        /// <param name="polygonsB">The polygons b.</param>
        /// <param name="outputAsCollectionType">Type of the output as collection.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
        public static List <Polygon> IntersectPolygons(this IEnumerable <Polygon> polygonsA, IEnumerable <Polygon> polygonsB, PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles,
                                                       double tolerance = double.NaN)
        {
            if (CLIPPER)
            {
                return(BooleanViaClipper(ClipperLib.PolyFillType.pftPositive, ClipperLib.ClipType.ctIntersection, polygonsA, polygonsB));
            }
            var polygonAList = new List <Polygon>(polygonsA);
            var polygonBList = polygonsB as List <Polygon> ?? polygonsB.ToList();

            if (double.IsNaN(tolerance))
            {
                tolerance = GetTolerancesFromPolygons(polygonAList, polygonBList);
            }

            foreach (var polyB in polygonBList)
            {
                for (int i = polygonAList.Count - 1; i >= 0; i--)
                {
                    var newPolygons = polygonAList[i].Intersect(polyB, outputAsCollectionType, tolerance);
                    polygonAList.RemoveAt(i);
                    foreach (var newPoly in newPolygons)
                    {
                        polygonAList.Insert(i, newPoly);
                    }
                }
            }
            return(polygonAList);
        }
コード例 #19
0
        /// <summary>
        /// Returns the list of polygons that are the subshapes of the two collections of polygons. Notice this is called UnionPolygons
        /// here to distinguish it from the LINQ function Union, which is also a valid extension for any IEnumerable collection.
        /// </summary>
        /// <param name="polygonsA">The polygons a.</param>
        /// <param name="polygonsB">The polygons b.</param>
        /// <param name="outputAsCollectionType">Type of the output as collection.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Collections.Generic.List&lt;TVGL.TwoDimensional.Polygon&gt;.</returns>
        public static List <Polygon> UnionPolygons(this IEnumerable <Polygon> polygonsA, IEnumerable <Polygon> polygonsB, PolygonCollection outputAsCollectionType = PolygonCollection.PolygonWithHoles,
                                                   double tolerance = double.NaN)
        {
            if (CLIPPER)
            {
                return(BooleanViaClipper(ClipperLib.PolyFillType.pftPositive, ClipperLib.ClipType.ctUnion, polygonsA, polygonsB));
            }

            var unionedPolygons = polygonsA.ToList();

            if (polygonsB is null)
            {
                return(UnionPolygons(unionedPolygons, outputAsCollectionType, tolerance));
            }
            var polygonBList = polygonsB.ToList();

            if (double.IsNaN(tolerance))
            {
                tolerance = GetTolerancesFromPolygons(unionedPolygons, polygonBList);
            }

            for (int i = unionedPolygons.Count - 1; i >= 0; i--)
            {
                for (int j = polygonBList.Count - 1; j >= 0; j--)
                {
                    var interaction = GetPolygonInteraction(unionedPolygons[i], polygonBList[j], tolerance);
                    if (interaction.Relationship == PolygonRelationship.BInsideA ||
                        interaction.Relationship == PolygonRelationship.Equal)
                    {  // remove polygon B
                        polygonBList.RemoveAt(j);
                    }
                    else if (interaction.Relationship == PolygonRelationship.AInsideB)
                    {                            // remove polygon A
                        unionedPolygons[i] = polygonBList[j];
                        polygonBList.RemoveAt(j);
                        break; // to stop the inner loop
                    }
                    else if (interaction.CoincidentEdges || interaction.Relationship == PolygonRelationship.Intersection)
                    {
                        //if (i == 1 && j == 0)
                        //Presenter.ShowAndHang(new[] { polygonList[i], polygonList[j] });
                        var newPolygons = Union(unionedPolygons[i], polygonBList[j], interaction, outputAsCollectionType, tolerance);
                        //Console.WriteLine("i = {0}, j = {1}", i, j);
                        //if (i == 1 && j == 0)
                        //Presenter.ShowAndHang(newPolygons);
                        unionedPolygons.RemoveAt(i);
                        polygonBList.RemoveAt(j);
                        unionedPolygons.AddRange(newPolygons);
                        i = unionedPolygons.Count; // to restart the outer loop
                        break;                     // to stop the inner loop
                    }
                }
            }
            return(UnionPolygons(unionedPolygons.Where(p => p.IsPositive), outputAsCollectionType, tolerance));
        }