/// <summary> /// Returns the projection of a point on the line defined with two other points. /// When the projection is out of the segment, then the closest extremity is returned. /// </summary> /// <exception cref="ArgumentNullException">None of the arguments can be null.</exception> /// <exception cref="ArgumentException">P1 and P2 must be different.</exception> /// <param name="Pt">Point to project.</param> /// <param name="P1">First point of the line.</param> /// <param name="P2">Second point of the line.</param> /// <returns>The projected point if it is on the segment / The closest extremity otherwise.</returns> public static Point3D ProjectOnLine(Point3D Pt, Point3D P1, Point3D P2) { if (Pt == null || P1 == null || P2 == null) { throw new ArgumentNullException("None of the arguments can be null."); } if (P1.Equals(P2)) { throw new ArgumentException("P1 and P2 must be different."); } Vector3D VLine = new Vector3D(P1, P2); Vector3D V1Pt = new Vector3D(P1, Pt); Vector3D Translation = VLine * (VLine | V1Pt) / VLine.SquareNorm; Point3D Projection = P1 + Translation; Vector3D V1Pjt = new Vector3D(P1, Projection); double D1 = V1Pjt | VLine; if (D1 < 0) { return(P1); } Vector3D V2Pjt = new Vector3D(P2, Projection); double D2 = V2Pjt | VLine; if (D2 > 0) { return(P2); } return(Projection); }
/// <summary> /// Returns the projection of a point on the line defined with two other points. /// When the projection is out of the segment, then the closest extremity is returned. /// </summary> /// <exception cref="ArgumentNullException">None of the arguments can be null.</exception> /// <exception cref="ArgumentException">P1 and P2 must be different.</exception> /// <param name="Pt">Point to project.</param> /// <param name="P1">First point of the line.</param> /// <param name="P2">Second point of the line.</param> /// <returns>The projected point if it is on the segment / The closest extremity otherwise.</returns> public static Point3D ProjectOnLine(Point3D Pt, Point3D P1, Point3D P2) { if ( Pt==null || P1==null || P2==null ) throw new ArgumentNullException("None of the arguments can be null."); if ( P1.Equals(P2) ) throw new ArgumentException("P1 and P2 must be different."); Vector3D VLine = new Vector3D(P1, P2); Vector3D V1Pt = new Vector3D(P1, Pt); Vector3D Translation = VLine*(VLine|V1Pt)/VLine.SquareNorm; Point3D Projection = P1+Translation; Vector3D V1Pjt = new Vector3D(P1, Projection); double D1 = V1Pjt|VLine; if ( D1<0 ) return P1; Vector3D V2Pjt = new Vector3D(P2, Projection); double D2 = V2Pjt|VLine; if ( D2>0 ) return P2; return Projection; }