|
@@ -78,6 +78,66 @@ THREE.Ray.prototype = {
|
|
|
|
|
|
}(),
|
|
|
|
|
|
+ distanceSqAndPointToSegment: function( v0, v1, optionalPointOnLine, optionalPointOnSegment ) {
|
|
|
+ // from http://www.geometrictools.com/LibMathematics/Distance/Wm5DistLine3Segment3.cpp
|
|
|
+ // It returns the min distance between the ray (actually... the line) and the segment
|
|
|
+ // defined by v0 and v1
|
|
|
+ // It can also set two optional targets :
|
|
|
+ // - The closest point on the ray (...line)
|
|
|
+ // - The closest point on the segment
|
|
|
+ var segCenter = v0.clone().add( v1 ).multiplyScalar( 0.5 );
|
|
|
+ var segDir = v1.clone().sub( v0 ).normalize();
|
|
|
+ var segExtent = v0.distanceTo( v1 ) *0.5;
|
|
|
+ var diff = this.origin.clone().sub( segCenter );
|
|
|
+ var a01 = -this.direction.dot( segDir );
|
|
|
+ var b0 = diff.dot( this.direction );
|
|
|
+ var c = diff.lengthSq();
|
|
|
+ var det = Math.abs( 1 - a01 * a01 );
|
|
|
+ var b1, s0, s1, sqrDist, extDet;
|
|
|
+ if( det >= 0 ) {
|
|
|
+ // The line and segment are not parallel.
|
|
|
+ b1 = -diff.dot( segDir );
|
|
|
+ s1 = a01 * b0 - b1;
|
|
|
+ extDet = segExtent * det;
|
|
|
+ if( s1 >= -extDet ) {
|
|
|
+ if( s1 <= extDet ) {
|
|
|
+ // Two interior points are closest, one on the line and one
|
|
|
+ // on the segment.
|
|
|
+ var invDet = 1 / det;
|
|
|
+ s0 = ( a01 * b1 - b0 ) * invDet;
|
|
|
+ s1 *= invDet;
|
|
|
+ sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // The endpoint e1 of the segment and an interior point of
|
|
|
+ // the line are closest.
|
|
|
+ s1 = segExtent;
|
|
|
+ s0 = - ( a01 * s1 + b0 );
|
|
|
+ sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // The end point e0 of the segment and an interior point of the
|
|
|
+ // line are closest.
|
|
|
+ s1 = - segExtent;
|
|
|
+ s0 = - ( a01 * s1 + b0 );
|
|
|
+ sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // The line and segment are parallel. Choose the closest pair so that
|
|
|
+ // one point is at segment center.
|
|
|
+ s1 = 0;
|
|
|
+ s0 = - b0;
|
|
|
+ sqrDist = b0 * s0 + c;
|
|
|
+ }
|
|
|
+ if(optionalPointOnLine)
|
|
|
+ optionalPointOnLine.copy( this.direction.clone().multiplyScalar( s0 ).add( this.origin ) );
|
|
|
+ if(optionalPointOnSegment)
|
|
|
+ optionalPointOnSegment.copy( segDir.clone().multiplyScalar( s1 ).add( segCenter ) );
|
|
|
+ return sqrDist;
|
|
|
+ },
|
|
|
+
|
|
|
isIntersectionSphere: function( sphere ) {
|
|
|
|
|
|
return ( this.distanceToPoint( sphere.center ) <= sphere.radius );
|