1 import { Matrix3 } from './Matrix3';
2 import { Vector3 } from './Vector3';
5 * @author bhouston / http://clara.io
8 function Plane( normal, constant ) {
10 // normal is assumed to be normalized
12 this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
13 this.constant = ( constant !== undefined ) ? constant : 0;
17 Object.assign( Plane.prototype, {
19 set: function ( normal, constant ) {
21 this.normal.copy( normal );
22 this.constant = constant;
28 setComponents: function ( x, y, z, w ) {
30 this.normal.set( x, y, z );
37 setFromNormalAndCoplanarPoint: function ( normal, point ) {
39 this.normal.copy( normal );
40 this.constant = - point.dot( this.normal );
46 setFromCoplanarPoints: function () {
48 var v1 = new Vector3();
49 var v2 = new Vector3();
51 return function setFromCoplanarPoints( a, b, c ) {
53 var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
55 // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
57 this.setFromNormalAndCoplanarPoint( normal, a );
67 return new this.constructor().copy( this );
71 copy: function ( plane ) {
73 this.normal.copy( plane.normal );
74 this.constant = plane.constant;
80 normalize: function () {
82 // Note: will lead to a divide by zero if the plane is invalid.
84 var inverseNormalLength = 1.0 / this.normal.length();
85 this.normal.multiplyScalar( inverseNormalLength );
86 this.constant *= inverseNormalLength;
101 distanceToPoint: function ( point ) {
103 return this.normal.dot( point ) + this.constant;
107 distanceToSphere: function ( sphere ) {
109 return this.distanceToPoint( sphere.center ) - sphere.radius;
113 projectPoint: function ( point, optionalTarget ) {
115 var result = optionalTarget || new Vector3();
117 return result.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point );
121 intersectLine: function () {
123 var v1 = new Vector3();
125 return function intersectLine( line, optionalTarget ) {
127 var result = optionalTarget || new Vector3();
129 var direction = line.delta( v1 );
131 var denominator = this.normal.dot( direction );
133 if ( denominator === 0 ) {
135 // line is coplanar, return origin
136 if ( this.distanceToPoint( line.start ) === 0 ) {
138 return result.copy( line.start );
142 // Unsure if this is the correct method to handle this case.
147 var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
149 if ( t < 0 || t > 1 ) {
155 return result.copy( direction ).multiplyScalar( t ).add( line.start );
161 intersectsLine: function ( line ) {
163 // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
165 var startSign = this.distanceToPoint( line.start );
166 var endSign = this.distanceToPoint( line.end );
168 return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
172 intersectsBox: function ( box ) {
174 return box.intersectsPlane( this );
178 intersectsSphere: function ( sphere ) {
180 return sphere.intersectsPlane( this );
184 coplanarPoint: function ( optionalTarget ) {
186 var result = optionalTarget || new Vector3();
188 return result.copy( this.normal ).multiplyScalar( - this.constant );
192 applyMatrix4: function () {
194 var v1 = new Vector3();
195 var m1 = new Matrix3();
197 return function applyMatrix4( matrix, optionalNormalMatrix ) {
199 var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
201 var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix );
203 var normal = this.normal.applyMatrix3( normalMatrix ).normalize();
205 this.constant = - referencePoint.dot( normal );
213 translate: function ( offset ) {
215 this.constant -= offset.dot( this.normal );
221 equals: function ( plane ) {
223 return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );