コード例 #1
0
ファイル: YuPengClipper.cs プロジェクト: netonjm/Rube.Net
        /// <summary>
        /// Implements "A new algorithm for Boolean operations on general polygons" 
        /// available here: http://liama.ia.ac.cn/wiki/_media/user:dong:dong_cg_05.pdf
        /// Merges two polygons, a subject and a clip with the specified operation. Polygons may not be 
        /// self-intersecting.
        /// 
        /// Warning: May yield incorrect results or even crash if polygons contain collinear points.
        /// </summary>
        /// <param name="subject">The subject polygon.</param>
        /// <param name="clip">The clip polygon, which is added, 
        /// substracted or intersected with the subject</param>
        /// <param name="clipType">The operation to be performed. Either
        /// Union, Difference or Intersection.</param>
        /// <param name="error">The error generated (if any)</param>
        /// <returns>A list of closed polygons, which make up the result of the clipping operation.
        /// Outer contours are ordered counter clockwise, holes are ordered clockwise.</returns>
        private static List<Vertices> Execute(Vertices subject, Vertices clip,
                                              PolyClipType clipType, out PolyClipError error)
        {
            Debug.Assert(subject.IsSimple() && clip.IsSimple(), "Non simple input!", "Input polygons must be simple (cannot intersect themselves).");

            // Copy polygons
            Vertices slicedSubject;
            Vertices slicedClip;
            // Calculate the intersection and touch points between
            // subject and clip and add them to both
            CalculateIntersections(subject, clip, out slicedSubject, out slicedClip);

            // Translate polygons into upper right quadrant
            // as the algorithm depends on it
            Vector2 lbSubject = subject.GetAABB().LowerBound;
            Vector2 lbClip = clip.GetAABB().LowerBound;
            Vector2 translate;
            Vector2.Min(ref lbSubject, ref lbClip, out translate);
            translate = Vector2.One - translate;
            if (translate != Vector2.Zero)
            {
                slicedSubject.Translate(ref translate);
                slicedClip.Translate(ref translate);
            }

            // Enforce counterclockwise contours
            slicedSubject.ForceCounterClockWise();
            slicedClip.ForceCounterClockWise();

            List<Edge> subjectSimplices;
            List<float> subjectCoeff;
            List<Edge> clipSimplices;
            List<float> clipCoeff;
            // Build simplical chains from the polygons and calculate the
            // the corresponding coefficients
            CalculateSimplicalChain(slicedSubject, out subjectCoeff, out subjectSimplices);
            CalculateSimplicalChain(slicedClip, out clipCoeff, out clipSimplices);

            List<Edge> resultSimplices;

            // Determine the characteristics function for all non-original edges
            // in subject and clip simplical chain and combine the edges contributing
            // to the result, depending on the clipType
            CalculateResultChain(subjectCoeff, subjectSimplices, clipCoeff, clipSimplices, clipType,
                                 out resultSimplices);

            List<Vertices> result;
            // Convert result chain back to polygon(s)
            error = BuildPolygonsFromChain(resultSimplices, out result);

            // Reverse the polygon translation from the beginning
            // and remove collinear points from output
            translate *= -1f;
            for (int i = 0; i < result.Count; ++i)
            {
                result[i].Translate(ref translate);
                SimplifyTools.CollinearSimplify(result[i]);
            }
            return result;
        }
コード例 #2
0
        /// <summary>
        ///     Implements "A new algorithm for Boolean operations on general polygons" available here:
        ///     http://liama.ia.ac.cn/wiki/_media/user:dong:dong_cg_05.pdf Merges two polygons, a subject and a clip with the
        ///     specified
        ///     operation. Polygons may not be self-intersecting. Warning: May yield incorrect results or even crash if polygons
        ///     contain collinear points.
        /// </summary>
        /// <param name="subject">The subject polygon.</param>
        /// <param name="clip">The clip polygon, which is added, substracted or intersected with the subject</param>
        /// <param name="clipType">The operation to be performed. Either Union, Difference or Intersection.</param>
        /// <param name="error">The error generated (if any)</param>
        /// <returns>
        ///     A list of closed polygons, which make up the result of the clipping operation. Outer contours are ordered
        ///     counter clockwise, holes are ordered clockwise.
        /// </returns>
        private static List <Vertices> Execute(Vertices subject, Vertices clip, PolyClipType clipType,
                                               out PolyClipError error)
        {
            Debug.Assert(subject.IsSimple() && clip.IsSimple(), "Non simple input!",
                         "Input polygons must be simple (cannot intersect themselves).");

            // Copy polygons

            // Calculate the intersection and touch points between
            // subject and clip and add them to both
            CalculateIntersections(subject, clip, out Vertices slicedSubject, out Vertices slicedClip);

            // Translate polygons into upper right quadrant
            // as the algorithm depends on it
            Vector2 lbSubject = subject.GetAabb().LowerBound;
            Vector2 lbClip    = clip.GetAabb().LowerBound;
            Vector2 translate = Vector2.Min(lbSubject, lbClip);

            translate = Vector2.One - translate;
            if (translate != Vector2.Zero)
            {
                slicedSubject.Translate(ref translate);
                slicedClip.Translate(ref translate);
            }

            // Enforce counterclockwise contours
            slicedSubject.ForceCounterClockWise();
            slicedClip.ForceCounterClockWise();

            // Build simplical chains from the polygons and calculate the
            // the corresponding coefficients
            CalculateSimplicalChain(slicedSubject, out List <float> subjectCoeff, out List <Edge> subjectSimplices);
            CalculateSimplicalChain(slicedClip, out List <float> clipCoeff, out List <Edge> clipSimplices);

            // Determine the characteristics function for all non-original edges
            // in subject and clip simplical chain and combine the edges contributing
            // to the result, depending on the clipType
            CalculateResultChain(subjectCoeff, subjectSimplices, clipCoeff, clipSimplices, clipType,
                                 out List <Edge> resultSimplices);

            // Convert result chain back to polygon(s)
            error = BuildPolygonsFromChain(resultSimplices, out List <Vertices> result);

            // Reverse the polygon translation from the beginning
            // and remove collinear points from output
            translate *= -1f;
            for (int i = 0; i < result.Count; ++i)
            {
                result[i].Translate(ref translate);
                SimplifyTools.CollinearSimplify(result[i]);
            }

            return(result);
        }
コード例 #3
0
 public static List<Vertices> Difference(Vertices polygon1, Vertices polygon2, out PolyClipError error)
 {
     return Execute(polygon1, polygon2, PolyClipType.Difference, out error);
 }
コード例 #4
0
        /// <summary>
        /// Prepares the polygons.
        /// </summary>
        /// <param name="polygon1">The polygon1.</param>
        /// <param name="polygon2">The polygon2.</param>
        /// <param name="poly1">The poly1.</param>
        /// <param name="poly2">The poly2.</param>
        /// <param name="intersections">The intersections.</param>
        /// <param name="error">The error.</param>
        /// <returns></returns>
        private static int PreparePolygons(Vertices polygon1, Vertices polygon2, out Vertices poly1, out Vertices poly2,
                                           out List <EdgeIntersectInfo> intersections, out PolyClipError error)
        {
            error = PolyClipError.None;

            // Make a copy of the polygons so that we dont modify the originals, and
            // force vertices to integer (pixel) values.
            //Note: We no longer use pixels. Rounding removed.
            poly1 = new Vertices(polygon1);

            poly2 = new Vertices(polygon2);

            // Find intersection points
            if (!VerticesIntersect(poly1, poly2, out intersections))
            {
                // No intersections found - polygons do not overlap.
                error = PolyClipError.NoIntersections;
                return(-1);
            }

            // Add intersection points to original polygons, ignoring existing points.
            foreach (EdgeIntersectInfo intersect in intersections)
            {
                if (!poly1.Contains(intersect.IntersectionPoint))
                {
                    poly1.Insert(poly1.IndexOf(intersect.EdgeOne.EdgeStart) + 1, intersect.IntersectionPoint);
                }

                if (!poly2.Contains(intersect.IntersectionPoint))
                {
                    poly2.Insert(poly2.IndexOf(intersect.EdgeTwo.EdgeStart) + 1, intersect.IntersectionPoint);
                }
            }

            // Find starting point on the edge of polygon1
            // that is outside of the intersected area
            // to begin polygon trace.
            int startingIndex = -1;
            int currentIndex  = 0;

            do
            {
                if (!poly2.PointInPolygonAngle(poly1[currentIndex]))
                {
                    startingIndex = currentIndex;
                    break;
                }
                currentIndex = poly1.NextIndex(currentIndex);
            } while (currentIndex != 0);

            // If we dont find a point on polygon1 thats outside of the
            // intersect area, the polygon1 must be inside of polygon2,
            // in which case, polygon2 IS the union of the two.
            if (startingIndex == -1)
            {
                error = PolyClipError.Poly1InsidePoly2;
            }

            return(startingIndex);
        }
コード例 #5
0
        /// <summary>
        /// Finds the intersection between two polygons.
        /// </summary>
        /// <param name="polygon1">The first polygon.</param>
        /// <param name="polygon2">The second polygon.</param>
        /// <param name="error">The error.</param>
        /// <returns>
        /// The intersection of the two polygons, or null if there was an error.
        /// </returns>
        public static Vertices Intersect(Vertices polygon1, Vertices polygon2, out PolyClipError error)
        {
            error = PolyClipError.None;

            Vertices poly1;
            Vertices poly2;
            List <EdgeIntersectInfo> intersections;

            PolyClipError gotError;
            int           startingIndex = PreparePolygons(polygon1, polygon2, out poly1, out poly2, out intersections,
                                                          out gotError);

            if (startingIndex == -1)
            {
                switch (gotError)
                {
                case PolyClipError.NoIntersections:
                    return(null);

                case PolyClipError.Poly1InsidePoly2:
                    return(polygon2);
                }
            }

            Vertices intersectOut = new Vertices();
            Vertices currentPoly  = poly1;
            Vertices otherPoly    = poly2;

            // Store the starting vertex so we can refer to it later.
            int     currentIndex   = poly1.IndexOf(intersections[0].IntersectionPoint);
            Vector2 startingVertex = poly1[currentIndex];

            do
            {
                // Add the current vertex to the final union
                intersectOut.Add(currentPoly[currentIndex]);

                foreach (EdgeIntersectInfo intersect in intersections)
                {
                    // If the current point is an intersection point
                    if (currentPoly[currentIndex] == intersect.IntersectionPoint)
                    {
                        // Make sure we want to swap polygons here.
                        int otherIndex = otherPoly.IndexOf(intersect.IntersectionPoint);

                        // If the next vertex, if we do swap, is inside the current polygon,
                        // then its safe to swap, otherwise, just carry on with the current poly.
                        if (currentPoly.PointInPolygonAngle(otherPoly[otherPoly.NextIndex(otherIndex)]))
                        {
                            // switch polygons
                            if (currentPoly == poly1)
                            {
                                currentPoly = poly2;
                                otherPoly   = poly1;
                            }
                            else
                            {
                                currentPoly = poly1;
                                otherPoly   = poly2;
                            }

                            // set currentIndex
                            currentIndex = otherIndex;

                            // Stop checking intersections for this point.
                            break;
                        }
                    }
                }

                // Move to next index
                currentIndex = currentPoly.NextIndex(currentIndex);
            } while ((currentPoly[currentIndex] != startingVertex) &&
                     (intersectOut.Count <= (poly1.Count + poly2.Count)));


            // If the number of vertices in the union is more than the combined vertices
            // of the input polygons, then something is wrong and the algorithm will
            // loop forever. Luckily, we check for that.
            if (intersectOut.Count > (poly1.Count + poly2.Count))
            {
                error = PolyClipError.InfiniteLoop;
            }

            return(intersectOut);
        }
コード例 #6
0
        private static List <Vertices> Execute(Vertices subject, Vertices clip, PolyClipType clipType, out PolyClipError error)
        {
            Debug.Assert(subject.IsSimple() && clip.IsSimple(), "Non simple input!", "Input polygons must be simple (cannot intersect themselves).");
            Vertices vertices;
            Vertices vertices2;

            YuPengClipper.CalculateIntersections(subject, clip, out vertices, out vertices2);
            TSVector2 lowerBound  = subject.GetAABB().LowerBound;
            TSVector2 lowerBound2 = clip.GetAABB().LowerBound;
            TSVector2 tSVector;

            TSVector2.Min(ref lowerBound, ref lowerBound2, out tSVector);
            tSVector = TSVector2.one - tSVector;
            bool flag = tSVector != TSVector2.zero;

            if (flag)
            {
                vertices.Translate(ref tSVector);
                vertices2.Translate(ref tSVector);
            }
            vertices.ForceCounterClockWise();
            vertices2.ForceCounterClockWise();
            List <FP> poly1Coeff;
            List <YuPengClipper.Edge> poly1Simplicies;

            YuPengClipper.CalculateSimplicalChain(vertices, out poly1Coeff, out poly1Simplicies);
            List <FP> poly2Coeff;
            List <YuPengClipper.Edge> poly2Simplicies;

            YuPengClipper.CalculateSimplicalChain(vertices2, out poly2Coeff, out poly2Simplicies);
            List <YuPengClipper.Edge> simplicies;

            YuPengClipper.CalculateResultChain(poly1Coeff, poly1Simplicies, poly2Coeff, poly2Simplicies, clipType, out simplicies);
            List <Vertices> list;

            error     = YuPengClipper.BuildPolygonsFromChain(simplicies, out list);
            tSVector *= -1f;
            for (int i = 0; i < list.Count; i++)
            {
                list[i].Translate(ref tSVector);
                SimplifyTools.CollinearSimplify(list[i], FP.Zero);
            }
            return(list);
        }
コード例 #7
0
 public static List <Vertices> Difference(Vertices polygon1, Vertices polygon2, out PolyClipError error)
 {
     return(Execute(polygon1, polygon2, PolyClipType.Difference, out error));
 }
コード例 #8
0
 public static List <Vertices> Union(Vertices polygon1, Vertices polygon2, out PolyClipError error)
 {
     return(Execute(polygon1, polygon2, PolyClipType.Union, out error));
 }
コード例 #9
0
 public static List <List <Vector2> > Intersect(
     List <Vector2> polygon1, List <Vector2> polygon2, out PolyClipError error)
 {
     return(Execute(polygon1, polygon2, PolyClipType.Intersect, out error));
 }
コード例 #10
0
 public static List <List <Vector2> > Difference(
     List <Vector2> polygon1, List <Vector2> polygon2, out PolyClipError error)
 {
     return(Execute(polygon1, polygon2, PolyClipType.Difference, out error));
 }
コード例 #11
0
 public static List <List <Vector2> > Union(List <Vector2> polygon1, List <Vector2> polygon2, out PolyClipError error)
 {
     return(Execute(polygon1, polygon2, PolyClipType.Union, out error));
 }
コード例 #12
0
ファイル: YuPengClipper.cs プロジェクト: yong-ja/starodyssey
 public static List<Polygon> Union(Polygon polygon1, Polygon polygon2, out PolyClipError error)
 {
     return Execute(polygon1, polygon2, PolyClipType.Union, out error);
 }
コード例 #13
0
ファイル: YuPengClipper.cs プロジェクト: yong-ja/starodyssey
 public static List<Polygon> Intersect(Polygon polygon1, Polygon polygon2, out PolyClipError error)
 {
     return Execute(polygon1, polygon2, PolyClipType.Intersect, out error);
 }
コード例 #14
0
ファイル: YuPengClipper.cs プロジェクト: yong-ja/starodyssey
 public static List<Polygon> Difference(Polygon polygon1, Polygon polygon2, out PolyClipError error)
 {
     return Execute(polygon1, polygon2, PolyClipType.Difference, out error);
 }
コード例 #15
0
 public static List<Vertices> Intersect(Vertices polygon1, Vertices polygon2, out PolyClipError error)
 {
     return Execute(polygon1, polygon2, PolyClipType.Intersect, out error);
 }
コード例 #16
0
 public static List<Vertices> Union(Vertices polygon1, Vertices polygon2, out PolyClipError error)
 {
     return Execute(polygon1, polygon2, PolyClipType.Union, out error);
 }
コード例 #17
0
        /// <summary>Actual algorithm.</summary>
        /// <param name="subject">The subject polygon.</param>
        /// <param name="clip">The clip polygon, which is added, subtracted or intersected with the subject</param>
        /// <param name="clipType">The operation to be performed. Either Union, Difference or Intersection.</param>
        /// <param name="error">The error generated (if any)</param>
        /// <returns>
        ///     A list of closed polygons, which make up the result of the clipping operation. Outer contours are ordered
        ///     counter clockwise, holes are ordered clockwise.
        /// </returns>
        private static List <List <Vector2> > Execute(
            IList <Vector2> subject, IList <Vector2> clip, PolyClipType clipType, out PolyClipError error)
        {
            if (!IsSimple(subject))
            {
                throw new ArgumentException(
                          "Input subject polygon must be simple (cannot intersect themselves).", "subject");
            }
            if (!IsSimple(clip))
            {
                throw new ArgumentException("Input clip polygon must be simple (cannot intersect themselves).", "clip");
            }

            // Copy polygons.
            List <Vector2> slicedSubject;
            List <Vector2> slicedClip;

            // Calculate the intersection and touch points between subject and clip and add them to both.
            CalculateIntersections(subject, clip, out slicedSubject, out slicedClip);

            // Translate polygons into upper right quadrant as the algorithm depends on it.
            var     lbSubject = GetLowerBound(subject);
            var     lbClip    = GetLowerBound(clip);
            Vector2 translate;

            Vector2.Min(ref lbSubject, ref lbClip, out translate);
            translate = Vector2.One - translate;
            if (translate != Vector2.Zero)
            {
                for (int i = 0, count = slicedSubject.Count; i < count; ++i)
                {
                    slicedSubject[i] += translate;
                }
                for (int i = 0, count = slicedClip.Count; i < count; ++i)
                {
                    slicedClip[i] += translate;
                }
            }

            // Enforce counterclockwise contours.
            ForceCounterClockWise(slicedSubject);
            ForceCounterClockWise(slicedClip);

            // Build simplical chains from the polygons and calculate the the corresponding coefficients.
            List <Edge>  subjectSimplices;
            List <float> subjectCoefficient;
            List <Edge>  clipSimplices;
            List <float> clipCoefficient;

            CalculateSimplicalChain(slicedSubject, out subjectCoefficient, out subjectSimplices);
            CalculateSimplicalChain(slicedClip, out clipCoefficient, out clipSimplices);

            // Determine the characteristics function for all non-original edges
            // in subject and clip simplical chain and combine the edges contributing
            // to the result, depending on the clipType
            var resultSimplices = CalculateResultChain(
                subjectCoefficient,
                subjectSimplices,
                clipCoefficient,
                clipSimplices,
                clipType);

            // Convert result chain back to polygon(s).
            List <List <Vector2> > result;

            error = BuildPolygonsFromChain(resultSimplices, out result);

            // Reverse the polygon translation from the beginning
            // and remove collinear points from output
            translate *= -1.0f;
            foreach (var vertices in result)
            {
                for (int i = 0, count = vertices.Count; i < count; ++i)
                {
                    vertices[i] += translate;
                }
                Simplification.CollinearSimplify(vertices);
            }
            return(result);
        }
コード例 #18
0
        /// <summary>
        /// Calculates the polygon(s) from the result simplical chain.
        /// </summary>
        /// <remarks>Used by method <c>Execute()</c>.</remarks>
        private static PolyClipError BuildPolygonsFromChain(List <Edge> simplicies, out List <Vertices> result)
        {
            result = new List <Vertices>();
            PolyClipError errVal = PolyClipError.None;

            while (simplicies.Count > 0)
            {
                Vertices output = new Vertices();
                output.Add(simplicies[0].EdgeStart);
                output.Add(simplicies[0].EdgeEnd);
                simplicies.RemoveAt(0);
                bool closed = false;
                int  index  = 0;
                int  count  = simplicies.Count; // Needed to catch infinite loops
                while (!closed && simplicies.Count > 0)
                {
                    if (VectorEqual(output[output.Count - 1], simplicies[index].EdgeStart))
                    {
                        if (VectorEqual(simplicies[index].EdgeEnd, output[0]))
                        {
                            closed = true;
                        }
                        else
                        {
                            output.Add(simplicies[index].EdgeEnd);
                        }
                        simplicies.RemoveAt(index);
                        --index;
                    }
                    else if (VectorEqual(output[output.Count - 1], simplicies[index].EdgeEnd))
                    {
                        if (VectorEqual(simplicies[index].EdgeStart, output[0]))
                        {
                            closed = true;
                        }
                        else
                        {
                            output.Add(simplicies[index].EdgeStart);
                        }
                        simplicies.RemoveAt(index);
                        --index;
                    }
                    if (!closed)
                    {
                        if (++index == simplicies.Count)
                        {
                            if (count == simplicies.Count)
                            {
                                result = new List <Vertices>();
                                Debug.WriteLine("Undefined error while building result polygon(s).");
                                return(PolyClipError.BrokenResult);
                            }
                            index = 0;
                            count = simplicies.Count;
                        }
                    }
                }
                if (output.Count < 3)
                {
                    errVal = PolyClipError.DegeneratedOutput;
                    Debug.WriteLine("Degenerated output polygon produced (vertices < 3).");
                }
                result.Add(output);
            }
            return(errVal);
        }
コード例 #19
0
ファイル: YuPengClipper.cs プロジェクト: jwmcglynn/float
        /// <summary>
        /// Implements "A new algorithm for Boolean operations on general polygons"
        /// available here: http://liama.ia.ac.cn/wiki/_media/user:dong:dong_cg_05.pdf
        /// Merges two polygons, a subject and a clip with the specified operation. Polygons may not be
        /// self-intersecting.
        ///
        /// Warning: May yield incorrect results or even crash if polygons contain colinear points.
        /// </summary>
        /// <param name="subject">The subject polygon.</param>
        /// <param name="clip">The clip polygon, which is added,
        /// substracted or intersected with the subject</param>
        /// <param name="clipType">The operation to be performed. Either
        /// Union, Difference or Intersection.</param>
        /// <param name="error">The error generated (if any)</param>
        /// <returns>A list of closed polygons, which make up the result of the clipping operation.
        /// Outer contours are ordered counter clockwise, holes are ordered clockwise.</returns>
        private static List <Vertices> Execute(Vertices subject, Vertices clip,
                                               PolyClipType clipType, out PolyClipError error)
        {
            if (!subject.IsSimple() || !clip.IsSimple())
            {
                error = PolyClipError.NonSimpleInput;
                Debug.WriteLine("Input polygons must be simple (cannot intersect themselves).");
                return(new List <Vertices>());
            }

            // Copy polygons
            Vertices slicedSubject;
            Vertices slicedClip;

            // Calculate the intersection and touch points between
            // subject and clip and add them to both
            CalculateIntersections(subject, clip, out slicedSubject, out slicedClip);

            // Translate polygons into upper right quadrant
            // as the algorithm depends on it
            Vector2 lbSubject = subject.GetCollisionBox().LowerBound;
            Vector2 lbClip    = clip.GetCollisionBox().LowerBound;
            Vector2 translate;

            Vector2.Min(ref lbSubject, ref lbClip, out translate);
            translate = Vector2.One - translate;
            if (translate != Vector2.Zero)
            {
                slicedSubject.Translate(ref translate);
                slicedClip.Translate(ref translate);
            }

            // Enforce counterclockwise contours
            slicedSubject.ForceCounterClockWise();
            slicedClip.ForceCounterClockWise();

            List <Edge>  subjectSimplices;
            List <float> subjectCoeff;
            List <Edge>  clipSimplices;
            List <float> clipCoeff;

            // Build simplical chains from the polygons and calculate the
            // the corresponding coefficients
            CalculateSimplicalChain(slicedSubject, out subjectCoeff, out subjectSimplices);
            CalculateSimplicalChain(slicedClip, out clipCoeff, out clipSimplices);

            List <float> subjectCharacter;
            List <float> clipCharacter;

            // Determine the characteristics function for all non-original edges
            // in subject and clip simplical chain
            CalculateEdgeCharacter(subjectCoeff, subjectSimplices, clipCoeff, clipSimplices,
                                   out subjectCharacter, out clipCharacter);

            List <Edge> resultSimplices;

            // Combine the edges contributing to the result, depending on the clipType
            CalculateResultChain(subjectSimplices, subjectCharacter, clipSimplices, clipCharacter, clipType,
                                 out resultSimplices);

            List <Vertices> result;

            // Convert result chain back to polygon(s)
            error = BuildPolygonsFromChain(resultSimplices, out result);

            // Reverse the polygon translation from the beginning
            translate *= -1f;
            for (int i = 0; i < result.Count; ++i)
            {
                result[i].Translate(ref translate);
            }
            return(result);
        }
コード例 #20
0
 public static List <Vertices> Intersect(Vertices polygon1, Vertices polygon2, out PolyClipError error)
 {
     return(Execute(polygon1, polygon2, PolyClipType.Intersect, out error));
 }
コード例 #21
0
        private static PolyClipError BuildPolygonsFromChain(List <YuPengClipper.Edge> simplicies, out List <Vertices> result)
        {
            result = new List <Vertices>();
            PolyClipError polyClipError = PolyClipError.None;
            PolyClipError result2;

            while (simplicies.Count > 0)
            {
                Vertices vertices = new Vertices();
                vertices.Add(simplicies[0].EdgeStart);
                vertices.Add(simplicies[0].EdgeEnd);
                simplicies.RemoveAt(0);
                bool flag  = false;
                int  num   = 0;
                int  count = simplicies.Count;
                while (!flag && simplicies.Count > 0)
                {
                    bool flag2 = YuPengClipper.VectorEqual(vertices[vertices.Count - 1], simplicies[num].EdgeStart);
                    if (flag2)
                    {
                        bool flag3 = YuPengClipper.VectorEqual(simplicies[num].EdgeEnd, vertices[0]);
                        if (flag3)
                        {
                            flag = true;
                        }
                        else
                        {
                            vertices.Add(simplicies[num].EdgeEnd);
                        }
                        simplicies.RemoveAt(num);
                        num--;
                    }
                    else
                    {
                        bool flag4 = YuPengClipper.VectorEqual(vertices[vertices.Count - 1], simplicies[num].EdgeEnd);
                        if (flag4)
                        {
                            bool flag5 = YuPengClipper.VectorEqual(simplicies[num].EdgeStart, vertices[0]);
                            if (flag5)
                            {
                                flag = true;
                            }
                            else
                            {
                                vertices.Add(simplicies[num].EdgeStart);
                            }
                            simplicies.RemoveAt(num);
                            num--;
                        }
                    }
                    bool flag6 = !flag;
                    if (flag6)
                    {
                        bool flag7 = ++num == simplicies.Count;
                        if (flag7)
                        {
                            bool flag8 = count == simplicies.Count;
                            if (flag8)
                            {
                                result = new List <Vertices>();
                                Debug.WriteLine("Undefined error while building result polygon(s).");
                                result2 = PolyClipError.BrokenResult;
                                return(result2);
                            }
                            num   = 0;
                            count = simplicies.Count;
                        }
                    }
                }
                bool flag9 = vertices.Count < 3;
                if (flag9)
                {
                    polyClipError = PolyClipError.DegeneratedOutput;
                    Debug.WriteLine("Degenerated output polygon produced (vertices < 3).");
                }
                result.Add(vertices);
            }
            result2 = polyClipError;
            return(result2);
        }