Browse Source

complete Plane unit tests. fix bugs with Plane.translate and Plane.transform.

Ben Houston 12 years ago
parent
commit
79e173ed55
2 changed files with 91 additions and 14 deletions
  1. 11 10
      src/math/Plane.js
  2. 80 4
      test/math/Plane.js

+ 11 - 10
src/math/Plane.js

@@ -4,7 +4,7 @@
 
 THREE.Plane = function ( normal, constant ) {
 
-	this.normal = normal !== undefined ? normal.clone() : new THREE.Vector3();
+	this.normal = normal !== undefined ? normal.clone() : new THREE.Vector3( 1, 0, 0 );
 	this.constant = constant !== undefined ? constant : 0;
 
 };
@@ -33,8 +33,8 @@ THREE.Plane.prototype = {
 
 	setFromNormalAndCoplanarPoint: function ( normal, point ) {
 
-		this.normal.copy( normal );
-		this.constant = - point.dot( normal );
+		this.normal.copy( normal ).normalize();
+		this.constant = - point.dot( this.normal );	// must be this.normal, not normal, as this.normal is normalized
 
 		return this;
 
@@ -43,7 +43,7 @@ THREE.Plane.prototype = {
 	setFromCoplanarPoints: function ( a, b, c ) {
 
 		var normal = THREE.Plane.__v1.sub( c, b ).crossSelf(
-					 THREE.Plane.__v2.sub( a, b ) );
+					 THREE.Plane.__v2.sub( a, b ) ).normalize();
 
 		// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
 
@@ -121,16 +121,17 @@ THREE.Plane.prototype = {
 
 	transform: function( matrix, optionalNormalMatrix ) {
 
+		var newNormal = THREE.Plane.__v1, newCoplanarPoint = THREE.Plane.__v2;
+
 		// compute new normal based on theory here:
 		// http://www.songho.ca/opengl/gl_normaltransform.html
 		optionalNormalMatrix = optionalNormalMatrix || new THREE.Matrix3().getInverse( matrix ).transpose();
-		THREE.Plane.__v1 = optionalNormalMatrix.multiplyVector3( this.normal );
+		newNormal = optionalNormalMatrix.multiplyVector3( newNormal.copy( this.normal ) );
 
-		// compute new co-planar point.
-		THREE.Plane.__v2 = this.projectPoint( THREE.Plane.__vZero, THREE.Plane.__v2 );
-		THREE.Plane.__v2 = matrix.multiplyVector3( THREE.Plane.__v2 );
+		newCoplanarPoint = this.coplanarPoint( newCoplanarPoint );
+		newCoplanarPoint = matrix.multiplyVector3( newCoplanarPoint );
 
-		this.setFromNormalAndCoplanarPoint( THREE.Plane.__v1, THREE.Plane.__v2 )
+		this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
 
 		return this;
 		
@@ -138,7 +139,7 @@ THREE.Plane.prototype = {
 
 	translate: function ( offset ) {
 
-		this.constant = - offset.dot( this.normal );
+		this.constant = this.constant - offset.dot( this.normal );
 
 		return this;
 

+ 80 - 4
test/math/Plane.js

@@ -4,9 +4,16 @@
 
 module( "Plane" );
 
+var comparePlane = function ( a, b, threshold ) {
+	threshold = threshold || 0.0001;
+	return ( a.normal.distanceTo( b.normal ) < threshold &&
+	Math.abs( a.constant - b.constant ) < threshold );
+};
+
+
 test( "constructor", function() {
 	var a = new THREE.Plane();
-	ok( a.normal.x == 0, "Passed!" );
+	ok( a.normal.x == 1, "Passed!" );
 	ok( a.normal.y == 0, "Passed!" );
 	ok( a.normal.z == 0, "Passed!" );
 	ok( a.constant == 0, "Passed!" );
@@ -45,7 +52,7 @@ test( "copy", function() {
 
 test( "set", function() {
 	var a = new THREE.Plane();
-	ok( a.normal.x == 0, "Passed!" );
+	ok( a.normal.x == 1, "Passed!" );
 	ok( a.normal.y == 0, "Passed!" );
 	ok( a.normal.z == 0, "Passed!" );
 	ok( a.constant == 0, "Passed!" );
@@ -59,7 +66,7 @@ test( "set", function() {
 
 test( "setComponents", function() {
 	var a = new THREE.Plane();
-	ok( a.normal.x == 0, "Passed!" );
+	ok( a.normal.x == 1, "Passed!" );
 	ok( a.normal.y == 0, "Passed!" );
 	ok( a.normal.z == 0, "Passed!" );
 	ok( a.constant == 0, "Passed!" );
@@ -74,7 +81,7 @@ test( "setComponents", function() {
 test( "setFromNormalAndCoplanarPoint", function() {
 	var a = new THREE.Plane().setFromNormalAndCoplanarPoint( one3, zero3 );
 	
-	ok( a.normal.equals( one3 ), "Passed!" );
+	ok( a.normal.equals( one3.clone().normalize() ), "Passed!" );
 	ok( a.constant == 0, "Passed!" );
 });
 
@@ -86,3 +93,72 @@ test( "normalize", function() {
 	ok( a.normal.equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" );
 	ok( a.constant == 1, "Passed!" );
 });
+
+test( "distanceToPoint", function() {
+	var a = new THREE.Plane( new THREE.Vector3( 2, 0, 0 ), -2 );
+	
+	a.normalize();
+	ok( a.distanceToPoint( a.projectPoint( zero3.clone() ) ) === 0, "Passed!" );
+	ok( a.distanceToPoint( new THREE.Vector3( 4, 0, 0 ) ) === 3, "Passed!" );
+});
+
+test( "distanceToSphere", function() {
+	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
+
+	var b = new THREE.Sphere( new THREE.Vector3( 2, 0, 0 ), 1 );
+	
+	ok( a.distanceToSphere( b ) === 1, "Passed!" );
+
+	a.set( new THREE.Vector3( 1, 0, 0 ), 2 );
+	ok( a.distanceToSphere( b ) === 3, "Passed!" );
+	a.set( new THREE.Vector3( 1, 0, 0 ), -2 );
+	ok( a.distanceToSphere( b ) === -1, "Passed!" );
+});
+
+test( "projectPoint", function() {
+	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
+
+	ok( a.projectPoint( new THREE.Vector3( 10, 0, 0 ) ).equals( zero3 ), "Passed!" );
+	ok( a.projectPoint( new THREE.Vector3( -10, 0, 0 ) ).equals( zero3 ), "Passed!" );
+
+	a = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), -1 );
+	ok( a.projectPoint( new THREE.Vector3( 0, 0, 0 ) ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
+	ok( a.projectPoint( new THREE.Vector3( 0, 1, 0 ) ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
+	
+});
+
+test( "orthoPoint", function() {
+	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
+
+	ok( a.orthoPoint( new THREE.Vector3( 10, 0, 0 ) ).equals( new THREE.Vector3( 10, 0, 0 ) ), "Passed!" );
+	ok( a.orthoPoint( new THREE.Vector3( -10, 0, 0 ) ).equals( new THREE.Vector3( -10, 0, 0 ) ), "Passed!" );
+});
+
+/*
+test( "isIntersectionLine", function() {
+});
+*/
+
+test( "coplanarPoint", function() {
+	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
+	ok( a.distanceToPoint( a.coplanarPoint() ) === 0, "Passed!" );
+
+	a = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), -1 );
+	ok( a.distanceToPoint( a.coplanarPoint() ) === 0, "Passed!" );
+});
+
+test( "transform/translate", function() {
+
+	var a = new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 );
+
+	var m = new THREE.Matrix4();
+	m.makeRotationZ( Math.PI * 0.5 );
+
+	ok( comparePlane( a.clone().transform( m ), new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 0 ) ), "Passed!" );
+
+	a = new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), -1 );
+	ok( comparePlane( a.clone().transform( m ), new THREE.Plane( new THREE.Vector3( -1, 0, 0 ), -1 ) ), "Passed!" );
+
+	m.makeTranslation( 1, 1, 1 );
+	ok( comparePlane( a.clone().transform( m ), a.clone().translate( new THREE.Vector3( 1, 1, 1 ) ) ), "Passed!" );
+});