예제 #1
0
        /// <summary>
        /// Tests if the supplied Polygon and this Polygon are coincident in any way when compared on a shared plane.
        /// </summary>
        /// <param name="polygon">The Polygon to compare to this Polygon.</param>
        /// <returns>
        /// Returns true if the supplied Polygon do not intersect or touch this Polygon when compared on a shared plane or if the supplied Polygon is null.
        /// </returns>
        public bool Disjoint(Polygon polygon)
        {
            if (polygon == null)
            {
                return(true);
            }
            var thisPath = this.ToClipperPath();
            var polyPath = polygon.ToClipperPath();

            foreach (IntPoint vertex in thisPath)
            {
                if (Clipper.PointInPolygon(vertex, polyPath) != 0)
                {
                    return(false);
                }
            }
            foreach (IntPoint vertex in polyPath)
            {
                if (Clipper.PointInPolygon(vertex, thisPath) != 0)
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Tests if the supplied Polygon is within this Polygon with or without edge coincident vertices when compared on a shared plane.
        /// </summary>
        /// <param name="polygon">The Polygon to compare to this Polygon.</param>
        /// <returns>
        /// Returns true if every vertex of the supplied Polygon is within this Polygon or coincident with an edge when compared on a shared plane. Returns false if any vertex of the supplied Polygon is outside this Polygon, or if the supplied Polygon is null.
        /// </returns>
        public bool Covers(Polygon polygon)
        {
            if (polygon == null)
            {
                return(false);
            }
            var clipper  = new Clipper();
            var solution = new List <List <IntPoint> >();

            clipper.AddPath(this.ToClipperPath(), PolyType.ptSubject, true);
            clipper.AddPath(polygon.ToClipperPath(), PolyType.ptClip, true);
            clipper.Execute(ClipType.ctIntersection, solution);
            if (solution.Count != 1)
            {
                return(false);
            }
            return(solution.First().ToPolygon().Area == polygon.ToClipperPath().ToPolygon().Area);
        }
예제 #3
0
        /// <summary>
        /// Constructs the geometric union between this Polygon and the supplied Polygon.
        /// </summary>
        /// <param name="polygon">The Polygon to be combined with this Polygon.</param>
        /// <param name="tolerance">An optional tolerance.</param>
        /// <returns>
        /// Returns a single Polygon from a successful union.
        /// Returns null if a union cannot be performed on the two Polygons.
        /// </returns>
        public Polygon Union(Polygon polygon, double tolerance = Vector3.EPSILON)
        {
            var     thisPath = this.ToClipperPath(tolerance);
            var     polyPath = polygon.ToClipperPath(tolerance);
            Clipper clipper  = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPath(polyPath, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctUnion, solution);
            if (solution.Count > 1)
            {
                return(null);
            }
            return(solution.First().ToPolygon(tolerance));
        }
예제 #4
0
        /// <summary>
        /// Tests if at least one point of an edge of the supplied Polygon is shared with an edge of this Polygon without the Polygons interesecting when compared on a shared plane.
        /// </summary>
        /// <param name="polygon">The Polygon to compare to this Polygon.</param>
        /// <param name="tolerance">An optional tolerance.</param>
        /// <returns>
        /// Returns true if the supplied Polygon shares at least one edge point with this Polygon without the Polygons intersecting when compared on a shared plane. Returns false if the Polygons intersect, are disjoint, or if the supplied Polygon is null.
        /// </returns>
        public bool Touches(Polygon polygon, double tolerance = Vector3.EPSILON)
        {
            if (polygon == null || this.Intersects(polygon))
            {
                return(false);
            }
            var thisPath = this.ToClipperPath(tolerance);
            var polyPath = polygon.ToClipperPath(tolerance);

            foreach (IntPoint vertex in thisPath)
            {
                if (Clipper.PointInPolygon(vertex, polyPath) == -1)
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #5
0
        /// <summary>
        /// Returns Polygons representing the symmetric difference between this Polygon and the supplied Polygon.
        /// </summary>
        /// <param name="polygon">The intersecting polygon.</param>
        /// <param name="tolerance">An optional tolerance.</param>
        /// <returns>
        /// Returns a list of Polygons representing the symmetric difference of this Polygon and the supplied Polygon.
        /// Returns a representation of this Polygon and the supplied Polygon if the Polygons do not intersect.
        /// </returns>
        public IList <Polygon> XOR(Polygon polygon, double tolerance = Vector3.EPSILON)
        {
            var     thisPath = this.ToClipperPath(tolerance);
            var     polyPath = polygon.ToClipperPath(tolerance);
            Clipper clipper  = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPath(polyPath, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctUnion, solution);
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path, tolerance));
            }
            return(polygons);
        }
예제 #6
0
        /// <summary>
        /// Tests if the supplied Polygon is within this Polygon with or without edge coincident vertices when compared on a shared plane.
        /// </summary>
        /// <param name="polygon">The Polygon to compare to this Polygon.</param>
        /// <returns>
        /// Returns true if every vertex of the supplied Polygon is within this Polygon or coincident with an edge when compared on a shared plane. Returns false if any vertex of the supplied Polygon is outside this Polygon, or if the supplied Polygon is null.
        /// </returns>
        public bool Covers(Polygon polygon)
        {
            if (polygon == null)
            {
                return(false);
            }
            if (this.IsClockWise() != polygon.IsClockWise())
            {
                polygon = polygon.Reversed();
            }
            var clipper  = new Clipper();
            var solution = new List <List <IntPoint> >();

            clipper.AddPath(this.ToClipperPath(), PolyType.ptSubject, true);
            clipper.AddPath(polygon.ToClipperPath(), PolyType.ptClip, true);
            clipper.Execute(ClipType.ctUnion, solution);
            if (solution.Count != 1)
            {
                return(false);
            }
            return(Math.Abs(solution.First().ToPolygon().Area() - this.ToClipperPath().ToPolygon().Area()) <= 0.0001);
        }
예제 #7
0
        /// <summary>
        /// Constructs the geometric difference between this Polygon and the supplied Polygon.
        /// </summary>
        /// <param name="polygon">The intersecting Polygon.</param>
        /// <param name="tolerance">An optional tolerance value.</param>
        /// <returns>
        /// Returns a list of Polygons representing the subtraction of the supplied Polygon from this Polygon.
        /// Returns null if the area of this Polygon is entirely subtracted.
        /// Returns a list containing a representation of the perimeter of this Polygon if the two Polygons do not intersect.
        /// </returns>
        public IList <Polygon> Difference(Polygon polygon, double tolerance = Vector3.EPSILON)
        {
            var     thisPath = this.ToClipperPath(tolerance);
            var     polyPath = polygon.ToClipperPath(tolerance);
            Clipper clipper  = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPath(polyPath, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctDifference, solution, PolyFillType.pftNonZero);
            if (solution.Count == 0)
            {
                return(null);
            }
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path, tolerance));
            }
            return(polygons);
        }
예제 #8
0
        /// <summary>
        /// Constructs the Polygon intersections between this Polygon and the supplied Polygon.
        /// </summary>
        /// <param name="polygon">The intersecting Polygon.</param>
        /// <returns>
        /// Returns a list of Polygons representing the intersection of this Polygon with the supplied Polygon.
        /// Returns null if the two Polygons do not intersect.
        /// </returns>
        public IList <Polygon> Intersection(Polygon polygon)
        {
            var     thisPath = this.ToClipperPath();
            var     polyPath = polygon.ToClipperPath();
            Clipper clipper  = new Clipper();

            clipper.AddPath(thisPath, PolyType.ptSubject, true);
            clipper.AddPath(polyPath, PolyType.ptClip, true);
            var solution = new List <List <IntPoint> >();

            clipper.Execute(ClipType.ctIntersection, solution);
            if (solution.Count == 0)
            {
                return(null);
            }
            var polygons = new List <Polygon>();

            foreach (List <IntPoint> path in solution)
            {
                polygons.Add(PolygonExtensions.ToPolygon(path));
            }
            return(polygons);
        }