Exemplo n.º 1
0
        /// <summary>
        /// Computes distance between two polygons.
        /// </summary>
        /// <remarks>
        /// To compute the distance, compute the distance
        /// between the rings of one polygon and the other polygon,
        /// and vice-versa.
        /// If the polygons intersect, then at least one ring must
        /// intersect the other polygon.
        /// Note that it is NOT sufficient to test only the shell rings.
        /// A counter-example is a "figure-8" polygon A
        /// and a simple polygon B at right angles to A, with the ring of B
        /// passing through the holes of A.
        /// The polygons intersect,
        /// but A's shell does not intersect B, and B's shell does not intersect A.</remarks>
        private void ComputeMinDistancePolygonPolygon(PlanarPolygon3D poly0, IPolygon poly1,
                                                      bool flip)
        {
            ComputeMinDistancePolygonRings(poly0, poly1, flip);
            if (_isDone)
            {
                return;
            }
            var polyPlane1 = new PlanarPolygon3D(poly1);

            ComputeMinDistancePolygonRings(polyPlane1, poly0.Polygon, flip);
        }
Exemplo n.º 2
0
        private static Coordinate Intersection(PlanarPolygon3D poly, ILineString line)
        {
            var seq = line.CoordinateSequence;

            if (seq.Count == 0)
            {
                return(null);
            }

            // start point of line
            var p0 = new Coordinate();

            seq.GetCoordinate(0, p0);
            double d0 = poly.Plane.OrientedDistance(p0);

            // for each segment in the line
            var p1 = new Coordinate();

            for (int i = 0; i < seq.Count - 1; i++)
            {
                seq.GetCoordinate(i, p0);
                seq.GetCoordinate(i + 1, p1);
                double d1 = poly.Plane.OrientedDistance(p1);

                /**
                 * If the oriented distances of the segment endpoints have the same sign,
                 * the segment does not cross the plane, and is skipped.
                 */
                if (d0 * d1 > 0)
                {
                    continue;
                }

                /**
                 * Compute segment-plane intersection point
                 * which is then used for a point-in-polygon test.
                 * The endpoint distances to the plane d0 and d1
                 * give the proportional distance of the intersection point
                 * along the segment.
                 */
                var intPt = SegmentPoint(p0, p1, d0, d1);
                // Coordinate intPt = polyPlane.intersection(p0, p1, s0, s1);
                if (poly.Intersects(intPt))
                {
                    return(intPt);
                }

                // shift to next segment
                d0 = d1;
            }
            return(null);
        }
Exemplo n.º 3
0
        /// <summary>Compute distance between a polygon and the rings of another.</summary>
        private void ComputeMinDistancePolygonRings(PlanarPolygon3D poly, IPolygon ringPoly,
                                                    bool flip)
        {
            // compute shell ring
            ComputeMinDistancePolygonLine(poly, ringPoly.ExteriorRing, flip);
            if (_isDone)
            {
                return;
            }
            // compute hole rings
            int nHole = ringPoly.NumInteriorRings;

            for (int i = 0; i < nHole; i++)
            {
                ComputeMinDistancePolygonLine(poly, ringPoly.GetInteriorRingN(i), flip);
                if (_isDone)
                {
                    return;
                }
            }
        }
Exemplo n.º 4
0
 /// <summary>Compute distance between a polygon and the rings of another.</summary>
 private void ComputeMinDistancePolygonRings(PlanarPolygon3D poly, IPolygon ringPoly,
     bool flip)
 {
     // compute shell ring
     ComputeMinDistancePolygonLine(poly, ringPoly.ExteriorRing, flip);
     if (_isDone) return;
     // compute hole rings
     int nHole = ringPoly.NumInteriorRings;
     for (int i = 0; i < nHole; i++)
     {
         ComputeMinDistancePolygonLine(poly, ringPoly.GetInteriorRingN(i), flip);
         if (_isDone) return;
     }
 }
Exemplo n.º 5
0
 /// <summary>
 /// Computes distance between two polygons.
 /// </summary>
 /// <remarks>
 /// To compute the distance, compute the distance
 /// between the rings of one polygon and the other polygon,
 /// and vice-versa.
 /// If the polygons intersect, then at least one ring must
 /// intersect the other polygon.
 /// Note that it is NOT sufficient to test only the shell rings. 
 /// A counter-example is a "figure-8" polygon A 
 /// and a simple polygon B at right angles to A, with the ring of B
 /// passing through the holes of A.
 /// The polygons intersect,
 /// but A's shell does not intersect B, and B's shell does not intersect A.</remarks>
 private void ComputeMinDistancePolygonPolygon(PlanarPolygon3D poly0, IPolygon poly1,
     bool flip)
 {
     ComputeMinDistancePolygonRings(poly0, poly1, flip);
     if (_isDone) return;
     var polyPlane1 = new PlanarPolygon3D(poly1);
     ComputeMinDistancePolygonRings(polyPlane1, poly0.Polygon, flip);
 }
Exemplo n.º 6
0
        private void ComputeMinDistancePolygonPoint(PlanarPolygon3D polyPlane, IPoint point,
            bool flip)
        {
            var pt = point.Coordinate;

            var shell = polyPlane.Polygon.ExteriorRing;
            if (polyPlane.Intersects(pt, shell))
            {
                // point is either inside or in a hole

                var nHole = polyPlane.Polygon.NumInteriorRings;
                for (int i = 0; i < nHole; i++)
                {
                    var hole = polyPlane.Polygon.GetInteriorRingN(i);
                    if (polyPlane.Intersects(pt, hole))
                    {
                        ComputeMinDistanceLinePoint(hole, point, flip);
                        return;
                    }
                }
                // point is in interior of polygon
                // distance is distance to polygon plane
                var dist = Math.Abs(polyPlane.Plane.OrientedDistance(pt));
                UpdateDistance(dist,
                               new GeometryLocation(polyPlane.Polygon, 0, pt),
                               new GeometryLocation(point, 0, pt),
                               flip
                    );
            }
            // point is outside polygon, so compute distance to shell linework
            ComputeMinDistanceLinePoint(shell, point, flip);
        }
Exemplo n.º 7
0
        private void ComputeMinDistancePolygonLine(PlanarPolygon3D poly, ILineString line,
            bool flip)
        {
            // first test if line intersects polygon
            var intPt = Intersection(poly, line);
            if (intPt != null)
            {
                UpdateDistance(0,
                               new GeometryLocation(poly.Polygon, 0, intPt),
                               new GeometryLocation(line, 0, intPt),
                               flip
                    );
                return;
            }

            // if no intersection, then compute line distance to polygon rings
            ComputeMinDistanceLineLine(poly.Polygon.ExteriorRing, line, flip);
            if (_isDone) return;
            int nHole = poly.Polygon.NumInteriorRings;
            for (int i = 0; i < nHole; i++)
            {
                ComputeMinDistanceLineLine(poly.Polygon.GetInteriorRingN(i), line, flip);
                if (_isDone) return;
            }
        }
Exemplo n.º 8
0
 private void ComputeMinDistanceOneMulti(PlanarPolygon3D poly, IGeometry geom, bool flip)
 {
     if (geom is IGeometryCollection)
     {
         int n = geom.NumGeometries;
         for (int i = 0; i < n; i++)
         {
             var g = geom.GetGeometryN(i);
             ComputeMinDistanceOneMulti(poly, g, flip);
             if (_isDone) return;
         }
     }
     else
     {
         if (geom is IPoint)
         {
             ComputeMinDistancePolygonPoint(poly, (IPoint)geom, flip);
             return;
         }
         if (geom is ILineString)
         {
             ComputeMinDistancePolygonLine(poly, (ILineString)geom, flip);
             return;
         }
         if (geom is IPolygon)
         {
             ComputeMinDistancePolygonPolygon(poly, (IPolygon)geom, flip);
             //return;
         }
     }
 }
Exemplo n.º 9
0
        private static Coordinate Intersection(PlanarPolygon3D poly, ILineString line)
        {
            var seq = line.CoordinateSequence;
            if (seq.Count == 0)
                return null;

            // start point of line
            var p0 = new Coordinate();
            seq.GetCoordinate(0, p0);
            var d0 = poly.Plane.OrientedDistance(p0);

            // for each segment in the line
            var p1 = new Coordinate();
            for (var i = 0; i < seq.Count - 1; i++)
            {
                seq.GetCoordinate(i, p0);
                seq.GetCoordinate(i + 1, p1);
                var d1 = poly.Plane.OrientedDistance(p1);

                /**
                 * If the oriented distances of the segment endpoints have the same sign,
                 * the segment does not cross the plane, and is skipped.
                 */
                if (d0 * d1 > 0)
                    continue;

                /**
                 * Compute segment-plane intersection point
                 * which is then used for a point-in-polygon test.
                 * The endpoint distances to the plane d0 and d1
                 * give the proportional distance of the intersection point
                 * along the segment.
                 */
                var intPt = SegmentPoint(p0, p1, d0, d1);
                // Coordinate intPt = polyPlane.intersection(p0, p1, s0, s1);
                if (poly.Intersects(intPt))
                {
                    return intPt;
                }

                // shift to next segment
                d0 = d1;
            }
            return null;
        }