Exemplo n.º 1
0
        /// <summary>
        /// Interpolate the segment on <paramref name="x"/>.
        /// </summary>
        /// <param name="segment">The segment to interpolate on.</param>
        /// <param name="x">The x value to use for interpolation.</param>
        /// <returns>The interpolated y value on the segment or <see cref="double.NaN"/>
        /// when no interpolation was found.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="segment"/> is <c>null</c>.</exception>
        public static double Interpolate(this Segment2D segment, double x)
        {
            if (segment == null)
            {
                throw new ArgumentNullException(nameof(segment));
            }

            double differenceInX = segment.SecondPoint.X - segment.FirstPoint.X;

            if (Math.Abs(differenceInX) < 1e-6)
            {
                return(double.NaN);
            }

            double m = (segment.SecondPoint.Y - segment.FirstPoint.Y) / differenceInX;
            double b = segment.FirstPoint.Y - (m * segment.FirstPoint.X);

            return(m * x + b);
        }
Exemplo n.º 2
0
        private static Point2D GetInterpolatedPoint(Segment2D lineSegment, double splitDistance)
        {
            double interpolationFactor = splitDistance / lineSegment.Length;

            return(GetInterpolatedPointAtFraction(lineSegment, interpolationFactor));
        }
Exemplo n.º 3
0
        private static Segment2DIntersectSegment2DResult HandleSegmentAsPointIntersectionDegenerates(Segment2D segment1, Segment2D segment2)
        {
            bool segment1IsPointDegenerate = IsSegmentActuallyPointDegenerate(segment1);
            bool segment2IsPointDegenerate = IsSegmentActuallyPointDegenerate(segment2);

            if (segment1IsPointDegenerate)
            {
                if (segment2IsPointDegenerate)
                {
                    // Both segments can be considered Point2D
                    return(segment1.FirstPoint.Equals(segment2.FirstPoint)
                               ? Segment2DIntersectSegment2DResult.CreateIntersectionResult(segment1.FirstPoint)
                               : Segment2DIntersectSegment2DResult.CreateNoIntersectResult());
                }

                return(IsPointInCollinearSegment(segment1.FirstPoint, segment2)
                           ? Segment2DIntersectSegment2DResult.CreateIntersectionResult(segment1.FirstPoint)
                           : Segment2DIntersectSegment2DResult.CreateNoIntersectResult());
            }

            return(IsPointInCollinearSegment(segment2.FirstPoint, segment1)
                       ? Segment2DIntersectSegment2DResult.CreateIntersectionResult(segment2.FirstPoint)
                       : Segment2DIntersectSegment2DResult.CreateNoIntersectResult());
        }
Exemplo n.º 4
0
 private static bool IsSegmentActuallyPointDegenerate(Segment2D segment)
 {
     return(segment.Length < epsilonForComparisons);
 }
Exemplo n.º 5
0
 private static bool IsSegmentAsPointIntersectionDegenerateScenario(Segment2D segment1, Segment2D segment2)
 {
     return(IsSegmentActuallyPointDegenerate(segment1) || IsSegmentActuallyPointDegenerate(segment2));
 }
Exemplo n.º 6
0
        private static Segment2DIntersectSegment2DResult HandleCollinearSegmentIntersection(Segment2D segment1, Segment2D segment2, Vector <double> v, Vector <double> w)
        {
            double          t0, t1;
            Vector <double> w2 = segment1.SecondPoint - segment2.FirstPoint;

            if (Math.Abs(v[0]) > double.Epsilon)
            {
                t0 = w[0] / v[0];
                t1 = w2[0] / v[0];
            }
            else
            {
                t0 = w[1] / v[1];
                t1 = w2[1] / v[1];
            }

            // Require t0 to be smaller than t1, swapping if needed:
            if (t0 > t1)
            {
                double tempSwapVariable = t0;
                t0 = t1;
                t1 = tempSwapVariable;
            }

            if (t0 > 1.0 || t1 < 0.0)
            {
                // There is no overlap:
                return(Segment2DIntersectSegment2DResult.CreateNoIntersectResult());
            }

            t0 = Math.Max(0.0, t0);
            t1 = Math.Min(1.0, t1);
            Point2D intersectionPoint1 = segment2.FirstPoint + v.Multiply(t0);

            if (Math.Abs(t0 - t1) < epsilonForComparisons)
            {
                // Segments intersect at a point:
                return(Segment2DIntersectSegment2DResult.CreateIntersectionResult(intersectionPoint1));
            }

            // Segments overlap:
            Point2D intersectionPoint2 = segment2.FirstPoint + v.Multiply(t1);

            return(Segment2DIntersectSegment2DResult.CreateOverlapResult(intersectionPoint1, intersectionPoint2));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Calculates the intersection between two 2D segments.
        /// </summary>
        /// <param name="segment1">The first 2D segment.</param>
        /// <param name="segment2">The second 2D segment.</param>
        /// <returns>The intersection calculation result.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="segment1"/> or
        /// <paramref name="segment2"/> is <c>null</c>.</exception>
        /// <remarks>Implementation from http://geomalgorithms.com/a05-_intersect-1.html
        /// based on method <c>intersect2D_2Segments</c>.</remarks>
        public static Segment2DIntersectSegment2DResult GetIntersectionBetweenSegments(Segment2D segment1, Segment2D segment2)
        {
            if (segment1 == null)
            {
                throw new ArgumentNullException(nameof(segment1));
            }

            if (segment2 == null)
            {
                throw new ArgumentNullException(nameof(segment2));
            }

            Vector <double> u = segment1.SecondPoint - segment1.FirstPoint;
            Vector <double> v = segment2.SecondPoint - segment2.FirstPoint;
            Vector <double> w = segment1.FirstPoint - segment2.FirstPoint;
            double          d = PerpDotProduct(u, v);

            if (Math.Abs(d) < epsilonForComparisons)
            {
                // Segments can be considered parallel...
                if (AreCollinear(u, v, w))
                {
                    // ... and collinear ...
                    if (IsSegmentAsPointIntersectionDegenerateScenario(segment1, segment2))
                    {
                        // ... but either or both segments are point degenerates:
                        return(HandleSegmentAsPointIntersectionDegenerates(segment1, segment2));
                    }

                    // ... so there is a possibility of overlapping or connected lines:
                    return(HandleCollinearSegmentIntersection(segment1, segment2, v, w));
                }

                // ... but not collinear, so no intersection possible:
                return(Segment2DIntersectSegment2DResult.CreateNoIntersectResult());
            }

            // Segments are at an angle and may intersect:
            double sI = PerpDotProduct(v, w) / d;

            if (sI < 0.0 || sI > 1.0)
            {
                return(Segment2DIntersectSegment2DResult.CreateNoIntersectResult());
            }

            double tI = PerpDotProduct(u, w) / d;

            if (tI < 0.0 || tI > 1.0)
            {
                return(Segment2DIntersectSegment2DResult.CreateNoIntersectResult());
            }

            Point2D intersectionPoint = segment1.FirstPoint + u.Multiply(sI);

            return(Segment2DIntersectSegment2DResult.CreateIntersectionResult(intersectionPoint));
        }