/// <summary> /// Computes the distance from a line segment AB to a line segment CD. /// Note: NON-ROBUST! /// </summary> /// <param name="A">A point of one line.</param> /// <param name="B">The second point of the line (must be different to A).</param> /// <param name="C">One point of the line.</param> /// <param name="D">Another point of the line (must be different to A).</param> /// <returns>The distance from line segment AB to line segment CD.</returns> public static double DistanceLineLine(Coordinate A, Coordinate B, Coordinate C, Coordinate D) { // check for zero-length segments if (A.Equals(B)) { return(DistanceComputer.PointToSegment(A, C, D)); } if (C.Equals(D)) { return(DistanceComputer.PointToSegment(D, A, B)); } // AB and CD are line segments /* * from comp.graphics.algo * * Solving the above for r and s yields * (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy) * r = ----------------------------- (eqn 1) * (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) * * (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) * s = ----------------------------- (eqn 2) * (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx) * * Let P be the position vector of the * intersection point, then * P=A+r(B-A) or * Px=Ax+r(Bx-Ax) * Py=Ay+r(By-Ay) * By examining the values of r & s, you can also determine some other limiting * conditions: * If 0<=r<=1 & 0<=s<=1, intersection exists * r<0 or r>1 or s<0 or s>1 line segments do not intersect * If the denominator in eqn 1 is zero, AB & CD are parallel * If the numerator in eqn 1 is also zero, AB & CD are collinear. */ double r_top = (A.Y - C.Y) * (D.X - C.X) - (A.X - C.X) * (D.Y - C.Y); double r_bot = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X); double s_top = (A.Y - C.Y) * (B.X - A.X) - (A.X - C.X) * (B.Y - A.Y); double s_bot = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X); if ((r_bot == 0) || (s_bot == 0)) { return(Math .Min( DistanceComputer.PointToSegment(A, C, D), Math.Min( DistanceComputer.PointToSegment(B, C, D), Math.Min(DistanceComputer.PointToSegment(C, A, B), DistanceComputer.PointToSegment(D, A, B))))); } double s = s_top / s_bot; double r = r_top / r_bot; if ((r < 0) || (r > 1) || (s < 0) || (s > 1)) { // no intersection return(Math .Min( DistanceComputer.PointToSegment(A, C, D), Math.Min( DistanceComputer.PointToSegment(B, C, D), Math.Min(DistanceComputer.PointToSegment(C, A, B), DistanceComputer.PointToSegment(D, A, B))))); } return(0.0); // intersection exists }
private static bool IsShallow(Coordinate p0, Coordinate p1, Coordinate p2, double distanceTol) { double dist = DistanceComputer.PointToSegment(p1, p0, p2); return(dist < distanceTol); }
/// <summary> /// Computes the distance between this line segment and a point. /// </summary> public double Distance(Coordinate p) { return(DistanceComputer.PointToSegment(p, _p0, _p1)); }