main/src/georegression/metric/ClosestPoint3D_F64.java
public static Point3D_F64 closestPoint(LineParametric3D_F64 l0,
										   LineParametric3D_F64 l1,
										   Point3D_F64 ret) {
		if( ret == null ) {
			ret = new Point3D_F64();
		}

		ret.x = l0.p.x - l1.p.x;
		ret.y = l0.p.y - l1.p.y;
		ret.z = l0.p.z - l1.p.z;

		// this solution is from: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/
		double dv01v1 = MiscOps.dot( ret, l1.slope );
		double dv1v0 = MiscOps.dot( l1.slope, l0.slope );
		double dv1v1 = MiscOps.dot( l1.slope, l1.slope );

		double t0 = dv01v1 * dv1v0 - MiscOps.dot( ret, l0.slope ) * dv1v1;
		double bottom = MiscOps.dot( l0.slope, l0.slope ) * dv1v1 - dv1v0 * dv1v0;
		if( bottom == 0 )
			return null;

		t0 /= bottom;

		// ( d1343 + mua d4321 ) / d4343
		double t1 = ( dv01v1 + t0 * dv1v0 ) / dv1v1;

		ret.x = (double) 0.5 * ( ( l0.p.x + t0 * l0.slope.x ) + ( l1.p.x + t1 * l1.slope.x ) );
		ret.y = (double) 0.5 * ( ( l0.p.y + t0 * l0.slope.y ) + ( l1.p.y + t1 * l1.slope.y ) );
		ret.z = (double) 0.5 * ( ( l0.p.z + t0 * l0.slope.z ) + ( l1.p.z + t1 * l1.slope.z ) );

		return ret;
	}
public static Point3D_F64 closestPoint(LineParametric3D_F64 l0,
										   LineParametric3D_F64 l1,
										   Point3D_F64 ret) {
		if( ret == null ) {
			ret = new Point3D_F64();
		}

		ret.x = l0.p.x - l1.p.x;
		ret.y = l0.p.y - l1.p.y;
		ret.z = l0.p.z - l1.p.z;

		// this solution is from: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/
		double dv01v1 = MiscOps.dot( ret, l1.slope );
		double dv1v0 = MiscOps.dot( l1.slope, l0.slope );
		double dv1v1 = MiscOps.dot( l1.slope, l1.slope );

		double t0 = dv01v1 * dv1v0 - MiscOps.dot( ret, l0.slope ) * dv1v1;
		double bottom = MiscOps.dot( l0.slope, l0.slope ) * dv1v1 - dv1v0 * dv1v0;
		if( bottom == 0 )
			return null;

		t0 /= bottom;

		// ( d1343 + mua d4321 ) / d4343
		double t1 = ( dv01v1 + t0 * dv1v0 ) / dv1v1;

		ret.x = (double) 0.5 * ( ( l0.p.x + t0 * l0.slope.x ) + ( l1.p.x + t1 * l1.slope.x ) );
		ret.y = (double) 0.5 * ( ( l0.p.y + t0 * l0.slope.y ) + ( l1.p.y + t1 * l1.slope.y ) );
		ret.z = (double) 0.5 * ( ( l0.p.z + t0 * l0.slope.z ) + ( l1.p.z + t1 * l1.slope.z ) );

		return ret;
	}
public static Point3D_F64 closestPoint ( LineParametric3D_F64 l0 , LineParametric3D_F64 l1 , Point3D_F64 ret ) { if ( ret == null ) { ret = new Point3D_F64 ( ) ; } ret . x = l0 . p . x - l1 . p . x ; ret . y = l0 . p . y - l1 . p . y ; ret . z = l0 . p . z - l1 . p . z ; // this solution is from: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/ double dv01v1 = MiscOps . dot ( ret , l1 . slope ) ; double dv1v0 = MiscOps . dot ( l1 . slope , l0 . slope ) ; double dv1v1 = MiscOps . dot ( l1 . slope , l1 . slope ) ; double t0 = dv01v1 * dv1v0 - MiscOps . dot ( ret , l0 . slope ) * dv1v1 ; double bottom = MiscOps . dot ( l0 . slope , l0 . slope ) * dv1v1 - dv1v0 * dv1v0 ; if ( bottom == 0 ) return null ; t0 /= bottom ; // ( d1343 + mua d4321 ) / d4343 double t1 = ( dv01v1 + t0 * dv1v0 ) / dv1v1 ; ret . x = ( double ) 0.5 * ( ( l0 . p . x + t0 * l0 . slope . x ) + ( l1 . p . x + t1 * l1 . slope . x ) ) ; ret . y = ( double ) 0.5 * ( ( l0 . p . y + t0 * l0 . slope . y ) + ( l1 . p . y + t1 * l1 . slope . y ) ) ; ret . z = ( double ) 0.5 * ( ( l0 . p . z + t0 * l0 . slope . z ) + ( l1 . p . z + t1 * l1 . slope . z ) ) ; return ret ; }
Returns the point which minimizes the distance between the two lines in 3D.  If the
two lines are parallel the result is undefined.

@param l0  first line. Not modified.
@param l1  second line. Not modified.
@param ret (Optional) Storage for the closest point. If null a new point is declared. Modified.
@return Closest point between two lines.
Returns the point which minimizes the distance between the two lines in 3D . If the two lines are parallel the result is undefined .