浏览代码

Triangle: new method .closestPointToPoint

* Triangle: new method .closestPointToPoint

* better initialization of variables
Michael Herzog 9 年之前
父节点
当前提交
6e05a92bc9
共有 3 个文件被更改,包括 103 次插入0 次删除
  1. 9 0
      docs/api/math/Triangle.html
  2. 63 0
      src/math/Triangle.js
  3. 31 0
      test/unit/math/Triangle.js

+ 9 - 0
docs/api/math/Triangle.html

@@ -131,6 +131,15 @@
 		Checks to see if the passed vector is within the triangle.
 		Checks to see if the passed vector is within the triangle.
 		</div>
 		</div>
 
 
+		<h3>[method:Vector3 closestPointToPoint]([page:Vector3 point], [page:Vector3 optionalTarget])</h3>
+		<div>
+		point -- [page:Vector3] <br />
+		optionalTarget -- Optional [page:Vector3] target to set the result.
+		</div>
+		<div>
+		Returns the closest point on the triangle.
+		</div>
+
 		<h3>[method:Triangle copy]([page:Triangle triangle])</h3>
 		<h3>[method:Triangle copy]([page:Triangle triangle])</h3>
 		<div>
 		<div>
 		triangle -- [page:Triangle]
 		triangle -- [page:Triangle]

+ 63 - 0
src/math/Triangle.js

@@ -183,6 +183,69 @@ THREE.Triangle.prototype = {
 
 
 	},
 	},
 
 
+	closestPointToPoint: function () {
+
+		var plane, edgeList, projectedPoint, closestPoint;
+
+		return function closestPointToPoint( point, optionalTarget ) {
+
+			if ( plane === undefined ) {
+
+				plane = new THREE.Plane();
+				edgeList = [ new THREE.Line3(), new THREE.Line3(), new THREE.Line3() ];
+				projectedPoint = new THREE.Vector3();
+				closestPoint = new THREE.Vector3();
+
+			}
+
+			var result = optionalTarget || new THREE.Vector3();
+			var minDistance = Infinity;
+
+			// project the point onto the plane of the triangle
+
+			plane.setFromCoplanarPoints( this.a, this.b, this.c );
+			plane.projectPoint( point, projectedPoint );
+
+			// check if the projection lies within the triangle
+
+			if( this.containsPoint( projectedPoint ) === true ) {
+
+				// if so, this is the closest point
+
+				result.copy( projectedPoint );
+
+			} else {
+
+				// if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices
+
+				edgeList[ 0 ].set( this.a, this.b );
+				edgeList[ 1 ].set( this.b, this.c );
+				edgeList[ 2 ].set( this.c, this.a );
+
+				for( var i = 0; i < edgeList.length; i ++ ) {
+
+					edgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint );
+
+					var distance = projectedPoint.distanceToSquared( closestPoint );
+
+					if( distance < minDistance ) {
+
+						minDistance = distance;
+
+						result.copy( closestPoint );
+
+					}
+
+				}
+
+			}
+
+			return result;
+
+		};
+
+	}(),
+
 	equals: function ( triangle ) {
 	equals: function ( triangle ) {
 
 
 		return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
 		return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );

+ 31 - 0
test/unit/math/Triangle.js

@@ -158,3 +158,34 @@ test( "containsPoint", function() {
 	ok( a.containsPoint( a.midpoint() ), "Passed!" );
 	ok( a.containsPoint( a.midpoint() ), "Passed!" );
 	ok( ! a.containsPoint( new THREE.Vector3( -1, -1, -1 ) ), "Passed!" );
 	ok( ! a.containsPoint( new THREE.Vector3( -1, -1, -1 ) ), "Passed!" );
 });
 });
+
+test( "closestPointToPoint", function() {
+
+	var a = new THREE.Triangle( new THREE.Vector3( -1, 0, 0 ), new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) );
+
+	// point lies inside the triangle
+	var b0 = a.closestPointToPoint( new THREE.Vector3( 0, 0.5, 0 ) );
+	ok( b0.equals( new THREE.Vector3( 0, 0.5, 0 ) ), "Passed!" );
+
+	// point lies on a vertex
+	b0 = a.closestPointToPoint( a.a );
+	ok( b0.equals( a.a ), "Passed!" );
+	b0 = a.closestPointToPoint( a.b );
+	ok( b0.equals( a.b ), "Passed!" );
+	b0 = a.closestPointToPoint( a.c );
+	ok( b0.equals( a.c ), "Passed!" );
+
+	// point lies on an edge
+	b0 = a.closestPointToPoint( zero3.clone() );
+	ok( b0.equals( zero3.clone() ), "Passed!" );
+
+	// point lies outside the triangle
+	b0 = a.closestPointToPoint( new THREE.Vector3( -2, 0, 0 ) );
+	ok( b0.equals( new THREE.Vector3( -1, 0, 0 ) ), "Passed!" );
+	b0 = a.closestPointToPoint( new THREE.Vector3( 2, 0, 0 ) );
+	ok( b0.equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" );
+	b0 = a.closestPointToPoint( new THREE.Vector3( 0, 2, 0 ) );
+	ok( b0.equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
+	b0 = a.closestPointToPoint( new THREE.Vector3( 0, -2, 0 ) );
+	ok( b0.equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
+});