/// <summary> /// Determines the squared distance between a point <paramref name="p"/> and a line segment defined by <paramref name="a"/> and <paramref name="b"/>. /// </summary> /// <param name="a">An end point of a segment.</param> /// <param name="b">An end point of a segment.</param> /// <param name="p">A point.</param> /// <returns>Squared distance from a point to a line segment.</returns> [Pure] public static double DistanceSquared(Point2 a, Point2 b, Point2 p) { Contract.Ensures( Contract.Result <double>() >= 0.0 || Double.IsNaN(Contract.Result <double>()) || Double.IsPositiveInfinity(Contract.Result <double>())); Point2.Order(ref a, ref b); var d = b - a; var v = p - a; var aDot = d.Dot(v); if (aDot <= 0) { return(v.GetMagnitudeSquared()); } var dMag = d.GetMagnitudeSquared(); return( (aDot >= dMag) ? (p - b).GetMagnitudeSquared() : Math.Max(0, v.GetMagnitudeSquared() - ((aDot * aDot) / dMag)) ); }
/// <summary> /// Determines if this line intersect another <paramref name="segment"/>. /// </summary> /// <param name="segment">A segment.</param> /// <returns><c>true</c> when another object intersects this object.</returns> public bool Intersects(Segment2 segment) { if (segment == null) { return(false); } var a = segment.A; var b = segment.B; Point2.Order(ref a, ref b); var d0 = b - a; var d1 = Direction; var e = P - a; var cross = (d0.X * d1.Y) - (d1.X * d0.Y); if (cross == 0.0) { return((e.X * d0.Y) - (e.Y * d0.X) == 0.0); } var s = ((e.X * d1.Y) - (e.Y * d1.X)) / cross; return(!(s < 0.0 || s > 1.0)); }
/// <summary> /// Calculates the intersection geometry between this ray and a segment. /// </summary> /// <param name="segment">The segment to find the intersection with.</param> /// <returns>The intersection geometry or <c>null</c> for no intersection.</returns> public IPlanarGeometry Intersection(Segment2 segment) { if (segment == null) { return(null); } var a = segment.A; var b = segment.B; Point2.Order(ref a, ref b); return(IntersectionSegment(a, b)); }
/// <inheritdoc/> public IPlanarGeometry Intersection(Segment2 segment) { if (segment == null) { return(null); } var a = segment.A; var b = segment.B; Point2.Order(ref a, ref b); var d0 = b - a; var d1 = Direction; var e = P - a; var tNumerator = (e.X * d0.Y) - (e.Y * d0.X); var cross = (d0.X * d1.Y) - (d1.X * d0.Y); if (cross == 0.0) { // parallel return(tNumerator == 0.0 ? new Segment2(a, b) : null); } // not parallel var s = ((e.X * d1.Y) - (e.Y * d1.X)) / cross; if (s < 0.0 || s > 1.0) { return(null); // not intersecting on this segment } if (s == 0.0) { return(a); } if (tNumerator == 0.0) { return(P); } return(a + d0.GetScaled(s)); // it must intersect at a point, so find where }
/// <summary> /// Determines the if a point <paramref name="p"/> intersects a line segment defined by <paramref name="a"/> and <paramref name="b"/>. /// </summary> /// <param name="a">An end point of a segment.</param> /// <param name="b">An end point of a segment.</param> /// <param name="p">A point.</param> /// <returns>True when a point intersects a line segment.</returns> [Pure] public static bool Intersects(Point2 a, Point2 b, Point2 p) { if (p.Equals(a) || p.Equals(b)) { return(true); } Point2.Order(ref a, ref b); var d = b - a; var v = p - a; var aDot = d.Dot(v); return( (aDot <= 0) ? (0 == v.X && 0 == v.Y) : ( !(aDot >= d.GetMagnitudeSquared()) && (d.X * v.Y) - (d.Y * v.X) == 0.0 ) ); }