Plane.js 4.4 KB

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