Ejemplo n.º 1
0
 /// <summary>
 /// Determines if the point is below the vertically projected segment intersection.
 /// </summary>
 /// <param name="yPtN">The y-coordinate of pt n.</param>
 /// <param name="yIntersection">The y-coordinate of the intersection of the projected line.</param>
 /// <param name="vertexI">The vertex i.</param>
 /// <param name="vertexJ">The vertex j.</param>
 /// <param name="includeEnds">if set to <c>true</c> [include ends].</param>
 /// <returns><c>true</c> if the point is below the vertically projected segment intersection, <c>false</c> otherwise.</returns>
 public static bool PointIsBelowSegmentIntersection(
     double yPtN,
     double yIntersection,
     Point vertexI,
     Point vertexJ,
     bool includeEnds = true)
 {
     return(yPtN < yIntersection &&
            ProjectionHorizontal.PointIsWithinSegmentHeight(yIntersection, vertexI, vertexJ, includeEnds: includeEnds));
 }
Ejemplo n.º 2
0
        /// <summary>
        /// The numbers of shape boundary intersections a vertical line makes when projecting to the top from the provided point.
        /// If the point is on a vertex or segment, the function returns either 0 or 1.
        /// </summary>
        /// <param name="coordinate">The coordinate.</param>
        /// <param name="shapeBoundary">The shape boundary composed of n points.</param>
        /// <param name="includePointOnSegment">if set to <c>true</c> [include point on segment].</param>
        /// <param name="includePointOnVertex">if set to <c>true</c> [include point on vertex].</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Int32.</returns>
        public static int NumberOfIntersections(
            Point coordinate,
            Point[] shapeBoundary,
            bool includePointOnSegment = true,
            bool includePointOnVertex  = true,
            double tolerance           = GeometryLibrary.ZeroTolerance)
        {
            if (shapeBoundary[0] != shapeBoundary[shapeBoundary.Length - 1])
            {
                throw new ArgumentException("Shape boundary describes a shape. Closure to the shape boundary is needed.");
            }

            // 1. Check vertical line projection from a pt. n to the top
            // 2. Count # of intersections of the line with shape edges

            // Note shape coordinates from XML already repeat starting node as an ending node.
            // No need to handle wrap-around below.

            int numberOfIntersections = 0;

            for (int i = 0; i < shapeBoundary.Length - 1; i++)
            {
                Point vertexI = shapeBoundary[i];
                if (PointIntersection.PointsOverlap(coordinate, vertexI))
                {
                    return(includePointOnVertex ? 1 : 0);
                }

                Point vertexJ = shapeBoundary[i + 1];

                if (!PointIsBelowSegmentBottom(coordinate.X, vertexI, vertexJ))
                {
                    // Pt is above the segment.
                    continue;
                }
                bool pointIsWithinSegmentWidth = PointIsWithinSegmentWidth(
                    coordinate.X,
                    vertexI, vertexJ,
                    includeEnds: includePointOnSegment);
                if (!pointIsWithinSegmentWidth)
                {
                    // Point is out of horizontal bounds of the segment extents.
                    continue;
                }
                bool pointIsWithinSegmentHeight = ProjectionHorizontal.PointIsWithinSegmentHeight(
                    coordinate.Y,
                    vertexI, vertexJ,
                    includeEnds: includePointOnSegment);
                if (Segment.IsHorizontal(vertexI, vertexJ))
                {
                    if (pointIsWithinSegmentHeight)
                    { // Point is on horizontal segment
                        return(includePointOnSegment ? 1 : 0);
                    }
                    // Point hits horizontal segment
                    numberOfIntersections++;
                    continue;
                }
                if (Segment.IsVertical(vertexI, vertexJ))
                {   // Segment would be parallel to line projection.
                    // Point is collinear since it is within segment height
                    if (pointIsWithinSegmentHeight)
                    { // Point is on vertical segment
                        return(includePointOnSegment ? 1 : 0);
                    }
                    continue;
                }

                double yIntersection = IntersectionPointY(coordinate.X, vertexI, vertexJ);
                if (PointIsBelowSegmentIntersection(coordinate.Y, yIntersection, vertexI, vertexJ))
                {
                    numberOfIntersections++;
                }
                else if (NMath.Abs(coordinate.Y - yIntersection) < tolerance)
                { // Point is on sloped segment
                    return(includePointOnSegment ? 1 : 0);
                }
            }
            return(numberOfIntersections);
        }