Browse Source

Ray: Add distanceSqToPoint method

Fixes #3385.
dubejf 10 years ago
parent
commit
0b1068cccf
5 changed files with 43 additions and 8 deletions
  1. 8 0
      docs/api/math/Ray.html
  2. 12 2
      src/math/Ray.js
  3. 4 3
      src/objects/PointCloud.js
  4. 3 3
      src/objects/Sprite.js
  5. 16 0
      test/unit/math/Ray.js

+ 8 - 0
docs/api/math/Ray.html

@@ -104,6 +104,14 @@
 		Get the distance of the closest approach between the [page:Ray] and the [page:Vector3].
 		</div>
 
+		<h3>[method:Float distanceSqToPoint]([page:Vector3 point])</h3>
+		<div>
+		point -- [page:Vector3] The [page:Vector3] to compute a distance to.
+		</div>
+		<div>
+		Get the squared distance of the closest approach between the [page:Ray] and the [page:Vector3].
+		</div>
+
 		<h3>[method:Boolean equals]([page:Ray ray])</h3>
 		<div>
 		ray -- [page:Ray] The [page:Ray] to compare to.

+ 12 - 2
src/math/Ray.js

@@ -71,6 +71,16 @@ THREE.Ray.prototype = {
 
 	distanceToPoint: function () {
 
+		return function ( point ) {
+
+			return Math.sqrt( this.distanceSqToPoint( point ) );
+
+		};
+
+	}(),
+
+	distanceSqToPoint: function () {
+
 		var v1 = new THREE.Vector3();
 
 		return function ( point ) {
@@ -81,13 +91,13 @@ THREE.Ray.prototype = {
 
 			if ( directionDistance < 0 ) {
 
-				return this.origin.distanceTo( point );
+				return this.origin.distanceToSquared( point );
 
 			}
 
 			v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
 
-			return v1.distanceTo( point );
+			return v1.distanceToSquared( point );
 
 		};
 

+ 4 - 3
src/objects/PointCloud.js

@@ -41,13 +41,14 @@ THREE.PointCloud.prototype.raycast = ( function () {
 		}
 
 		var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
+		var localThresholdSq = localThreshold * localThreshold;
 		var position = new THREE.Vector3();
 
 		var testPoint = function ( point, index ) {
 
-			var rayPointDistance = ray.distanceToPoint( point );
+			var rayPointDistanceSq = ray.distanceSqToPoint( point );
 
-			if ( rayPointDistance < localThreshold ) {
+			if ( rayPointDistanceSq < localThresholdSq ) {
 
 				var intersectPoint = ray.closestPointToPoint( point );
 				intersectPoint.applyMatrix4( object.matrixWorld );
@@ -59,7 +60,7 @@ THREE.PointCloud.prototype.raycast = ( function () {
 				intersects.push( {
 
 					distance: distance,
-					distanceToRay: rayPointDistance,
+					distanceToRay: Math.sqrt( rayPointDistanceSq ),
 					point: intersectPoint.clone(),
 					index: index,
 					face: null,

+ 3 - 3
src/objects/Sprite.js

@@ -38,9 +38,9 @@ THREE.Sprite.prototype.raycast = ( function () {
 
 		matrixPosition.setFromMatrixPosition( this.matrixWorld );
 
-		var distance = raycaster.ray.distanceToPoint( matrixPosition );
+		var distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition );
 
-		if ( distance > this.scale.x ) {
+		if ( distanceSq > this.scale.x * this.scale.x ) {
 
 			return;
 
@@ -48,7 +48,7 @@ THREE.Sprite.prototype.raycast = ( function () {
 
 		intersects.push( {
 
-			distance: distance,
+			distance: Math.sqrt( distanceSq ),
 			point: this.position,
 			face: null,
 			object: this

+ 16 - 0
test/unit/math/Ray.js

@@ -93,6 +93,22 @@ test( "distanceToPoint", function() {
 	ok( d === 0, "Passed!" );
 });
 
+test( "distanceSqToPoint", function() {
+	var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) );
+
+	// behind the ray
+	var b = a.distanceSqToPoint( zero3 );
+	ok( b === 3, "Passed!" );
+
+	// front of the ray
+	var c = a.distanceSqToPoint( new THREE.Vector3( 0, 0, 50 ) );
+	ok( c === 2, "Passed!" );
+
+	// exactly on the ray
+	var d = a.distanceSqToPoint( one3 );
+	ok( d === 0, "Passed!" );
+});
+
 test( "isIntersectionSphere", function() {
 	var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) );
 	var b = new THREE.Sphere( zero3, 0.5 );