Exemple #1
0
 /// <summary>
 /// Performs one or more polygon operations on the 2 provided polygons
 /// </summary>
 /// <param name="polygon1">The first polygon.</param>
 /// <param name="polygon2">The second polygon</param>
 /// <param name="subtract">The result of the polygon subtraction</param>
 /// <returns>error code</returns>
 public static PolygonUtil.PolyUnionError PolygonOperation(PolygonUtil.PolyOperation operations, Point2DList polygon1, Point2DList polygon2, out Dictionary<uint, Point2DList> results)
 {
     PolygonOperationContext ctx = new PolygonOperationContext();
     ctx.Init(operations, polygon1, polygon2);
     results = ctx.mOutput;
     return PolygonUtil.PolygonOperation(ctx);
 }
Exemple #2
0
        public bool Init(PolygonUtil.PolyOperation operations, Point2DList polygon1, Point2DList polygon2)
        {
            Clear();

            mOperations = operations;
            mOriginalPolygon1 = polygon1;
            mOriginalPolygon2 = polygon2;

            // Make a copy of the polygons so that we dont modify the originals, and
            // force vertices to integer (pixel) values.
            mPoly1 = new Point2DList(polygon1);
            mPoly1.WindingOrder = Point2DList.WindingOrderType.Default;
            mPoly2 = new Point2DList(polygon2);
            mPoly2.WindingOrder = Point2DList.WindingOrderType.Default;

            // Find intersection points
            if (!VerticesIntersect(mPoly1, mPoly2, out mIntersections))
            {
                // No intersections found - polygons do not overlap.
                mError = PolygonUtil.PolyUnionError.NoIntersections;
                return false;
            }

            // make sure edges that intersect more than once are updated to have correct start points
            int numIntersections = mIntersections.Count;
            for (int i = 0; i < numIntersections; ++i)
            {
                for (int j = i + 1; j < numIntersections; ++j)
                {
                    if (mIntersections[i].EdgeOne.EdgeStart.Equals(mIntersections[j].EdgeOne.EdgeStart) &&
                        mIntersections[i].EdgeOne.EdgeEnd.Equals(mIntersections[j].EdgeOne.EdgeEnd))
                    {
                        mIntersections[j].EdgeOne.EdgeStart = mIntersections[i].IntersectionPoint;
                    }
                    if (mIntersections[i].EdgeTwo.EdgeStart.Equals(mIntersections[j].EdgeTwo.EdgeStart) &&
                        mIntersections[i].EdgeTwo.EdgeEnd.Equals(mIntersections[j].EdgeTwo.EdgeEnd))
                    {
                        mIntersections[j].EdgeTwo.EdgeStart = mIntersections[i].IntersectionPoint;
                    }
                }
            }

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

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

            mPoly1VectorAngles = new List<int>();
            for (int i = 0; i < mPoly2.Count; ++i)
            {
                mPoly1VectorAngles.Add(-1);
            }
            mPoly2VectorAngles = new List<int>();
            for (int i = 0; i < mPoly1.Count; ++i)
            {
                mPoly2VectorAngles.Add(-1);
            }

            // Find starting point on the edge of polygon1 that is outside of
            // the intersected area to begin polygon trace.
            int currentIndex = 0;
            do
            {
                bool bPointInPolygonAngle = PointInPolygonAngle(mPoly1[currentIndex], mPoly2);
                mPoly2VectorAngles[currentIndex] = bPointInPolygonAngle ? 1 : 0;
                if (bPointInPolygonAngle)
                {
                    mStartingIndex = currentIndex;
                    break;
                }
                currentIndex = mPoly1.NextIndex(currentIndex);
            } while (currentIndex != 0);

            // If we don't 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 (mStartingIndex == -1)
            {
                mError = PolygonUtil.PolyUnionError.Poly1InsidePoly2;
                return false;
            }

            return true;
        }