Plane.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /**
  2. * @author bhouston / http://clara.io
  3. */
  4. THREE.Plane = function ( normal, constant ) {
  5. this.normal = ( normal !== undefined ) ? normal : new THREE.Vector3( 1, 0, 0 );
  6. this.constant = ( constant !== undefined ) ? constant : 0;
  7. };
  8. THREE.Plane.prototype = {
  9. constructor: THREE.Plane,
  10. set: function ( normal, constant ) {
  11. this.normal.copy( normal );
  12. this.constant = constant;
  13. return this;
  14. },
  15. setComponents: function ( x, y, z, w ) {
  16. this.normal.set( x, y, z );
  17. this.constant = w;
  18. return this;
  19. },
  20. setFromNormalAndCoplanarPoint: function ( normal, point ) {
  21. this.normal.copy( normal );
  22. this.constant = - point.dot( this.normal ); // must be this.normal, not normal, as this.normal is normalized
  23. return this;
  24. },
  25. setFromCoplanarPoints: function () {
  26. var v1 = new THREE.Vector3();
  27. var v2 = new THREE.Vector3();
  28. return function ( a, b, c ) {
  29. var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
  30. // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
  31. this.setFromNormalAndCoplanarPoint( normal, a );
  32. return this;
  33. };
  34. }(),
  35. clone: function () {
  36. return new this.constructor().copy( this );
  37. },
  38. copy: function ( plane ) {
  39. this.normal.copy( plane.normal );
  40. this.constant = plane.constant;
  41. return this;
  42. },
  43. normalize: function () {
  44. // Note: will lead to a divide by zero if the plane is invalid.
  45. var inverseNormalLength = 1.0 / this.normal.length();
  46. this.normal.multiplyScalar( inverseNormalLength );
  47. this.constant *= inverseNormalLength;
  48. return this;
  49. },
  50. negate: function () {
  51. this.constant *= - 1;
  52. this.normal.negate();
  53. return this;
  54. },
  55. distanceToPoint: function ( point ) {
  56. return this.normal.dot( point ) + this.constant;
  57. },
  58. distanceToSphere: function ( sphere ) {
  59. return this.distanceToPoint( sphere.center ) - sphere.radius;
  60. },
  61. projectPoint: function ( point, optionalTarget ) {
  62. return this.orthoPoint( point, optionalTarget ).sub( point ).negate();
  63. },
  64. orthoPoint: function ( point, optionalTarget ) {
  65. var perpendicularMagnitude = this.distanceToPoint( point );
  66. var result = optionalTarget || new THREE.Vector3();
  67. return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
  68. },
  69. intersectLine: function () {
  70. var v1 = new THREE.Vector3();
  71. return function ( line, optionalTarget ) {
  72. var result = optionalTarget || new THREE.Vector3();
  73. var direction = line.delta( v1 );
  74. var denominator = this.normal.dot( direction );
  75. if ( denominator === 0 ) {
  76. // line is coplanar, return origin
  77. if ( this.distanceToPoint( line.start ) === 0 ) {
  78. return result.copy( line.start );
  79. }
  80. // Unsure if this is the correct method to handle this case.
  81. return undefined;
  82. }
  83. var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
  84. if ( t < 0 || t > 1 ) {
  85. return undefined;
  86. }
  87. return result.copy( direction ).multiplyScalar( t ).add( line.start );
  88. };
  89. }(),
  90. intersectsLine: function ( line ) {
  91. // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
  92. var startSign = this.distanceToPoint( line.start );
  93. var endSign = this.distanceToPoint( line.end );
  94. return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
  95. },
  96. isIntersectionLine: function ( line ) {
  97. console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );
  98. return this.intersectsLine( line );
  99. },
  100. coplanarPoint: function ( optionalTarget ) {
  101. var result = optionalTarget || new THREE.Vector3();
  102. return result.copy( this.normal ).multiplyScalar( - this.constant );
  103. },
  104. applyMatrix4: function () {
  105. var v1 = new THREE.Vector3();
  106. var v2 = new THREE.Vector3();
  107. var m1 = new THREE.Matrix3();
  108. return function ( matrix, optionalNormalMatrix ) {
  109. // compute new normal based on theory here:
  110. // http://www.songho.ca/opengl/gl_normaltransform.html
  111. var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
  112. var newNormal = v1.copy( this.normal ).applyMatrix3( normalMatrix );
  113. var newCoplanarPoint = this.coplanarPoint( v2 );
  114. newCoplanarPoint.applyMatrix4( matrix );
  115. this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
  116. return this;
  117. };
  118. }(),
  119. translate: function ( offset ) {
  120. this.constant = this.constant - offset.dot( this.normal );
  121. return this;
  122. },
  123. equals: function ( plane ) {
  124. return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
  125. }
  126. };