Example #1
0
        /// <summary>
        /// The y-coordinate of the intersection of the vertically projected line with the provided segment.
        /// </summary>
        /// <param name="xPtN">The x-coordinate of pt n, where the projection starts.</param>
        /// <param name="ptI">Vertex i of the segment.</param>
        /// <param name="ptJ">Vertex j of the segment.</param>
        /// <returns>System.Double.</returns>
        public static double IntersectionPointY(
            double xPtN,
            CartesianCoordinate ptI,
            CartesianCoordinate ptJ)
        {
            if (LinearCurve.IsVertical(ptI, ptJ))
            {
                throw new ArgumentException("Segment is vertical, so intersection point is either infinity or NAN.");
            }

            LinearCurve curve = new LinearCurve(ptI, ptJ);

            return(curve.Y(xPtN));
        }
Example #2
0
        /// <summary>
        /// The numbers of shape boundary intersections a horizontal line makes when projecting to the right from the provided point.
        /// An odd number indicates the point is inside the shape.
        /// An even number indicates the point is outside the shape.
        /// If the point is on a vertex or segment, the function returns 0.
        /// </summary>
        /// <param name="coordinate">The coordinate.</param>
        /// <param name="shapeBoundary">The shape boundary composed of n points.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>System.Int32.</returns>
        /// <exception cref="System.ArgumentException">Shape boundary describes a shape. Closure to the shape boundary is needed.</exception>
        public static int NumberOfIntersectionsOnHorizontalProjection(
            CartesianCoordinate coordinate,
            CartesianCoordinate[] shapeBoundary,
            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 horizontal line projection from a pt. n to the right
            // 2. Count # of intersections of the line with shape edges

            int currentNumberOfIntersections = 0;

            for (int i = 0; i < shapeBoundary.Length - 1; i++)
            {
                CartesianCoordinate vertexI = shapeBoundary[i];
                if (PointIntersection.IsOnPoint(coordinate, vertexI))
                {   // Pt lies on vertex
                    return(0);
                }

                CartesianCoordinate vertexJ = shapeBoundary[i + 1];
                LineSegment         segment = new LineSegment(vertexI, vertexJ);
                if (segment.IncludesCoordinate(coordinate))
                {   // Pt lies on boundary
                    return(0);
                }

                if (!PointIsLeftOfLineEndInclusive(coordinate.X, vertexI, vertexJ))
                {   // Pt is to the right of the line segment.
                    continue;
                }

                if (!PointIsWithinLineHeightInclusive(coordinate.Y, vertexI, vertexJ))
                {   // Pt is out of vertical bounds of the line segment.
                    continue;
                }

                LinearCurve segmentCurve = segment.Curve;
                if (segmentCurve.IsHorizontal())
                {   // Projection is tangent to segment
                    continue;
                }

                if (pointHorizontalProjectionIntersectsVertex(coordinate, vertexI))
                {   // Projection hits vertex at point I. Do offset check on current segment
                    if (slopeIsDownwardBetweenCoordinates(vertexI, vertexJ, tolerance))
                    {
                        continue;
                    }
                    currentNumberOfIntersections++;
                    continue;
                }
                if (pointHorizontalProjectionIntersectsVertex(coordinate, vertexJ))
                {   // Projection hits vertex at point J. Do offset check on current segment
                    if (slopeIsDownwardBetweenCoordinates(vertexJ, vertexI, tolerance))
                    {
                        continue;
                    }
                    currentNumberOfIntersections++;
                    continue;
                }

                if (segmentCurve.IsVertical())
                {   // Projection hits vertical segment
                    currentNumberOfIntersections++;
                    continue;
                }

                currentNumberOfIntersections += numberOfIntersectionsHorizontal(coordinate, vertexI, vertexJ);
            }
            return(currentNumberOfIntersections);
        }