Triangle.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /**
  2. * @author bhouston / http://exocortex.com
  3. * @author mrdoob / http://mrdoob.com/
  4. */
  5. THREE.Triangle = function ( a, b, c ) {
  6. this.a = ( a !== undefined ) ? a : new THREE.Vector3();
  7. this.b = ( b !== undefined ) ? b : new THREE.Vector3();
  8. this.c = ( c !== undefined ) ? c : new THREE.Vector3();
  9. };
  10. THREE.Triangle.normal = function () {
  11. var v0 = new THREE.Vector3();
  12. return function ( a, b, c, optionalTarget ) {
  13. var result = optionalTarget || new THREE.Vector3();
  14. result.subVectors( c, b );
  15. v0.subVectors( a, b );
  16. result.cross( v0 );
  17. var resultLengthSq = result.lengthSq();
  18. if ( resultLengthSq > 0 ) {
  19. return result.multiplyScalar( 1 / Math.sqrt( resultLengthSq ) );
  20. }
  21. return result.set( 0, 0, 0 );
  22. };
  23. }();
  24. // static/instance method to calculate barycentric coordinates
  25. // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
  26. THREE.Triangle.barycoordFromPoint = function () {
  27. var v0 = new THREE.Vector3();
  28. var v1 = new THREE.Vector3();
  29. var v2 = new THREE.Vector3();
  30. return function ( point, a, b, c, optionalTarget ) {
  31. v0.subVectors( c, a );
  32. v1.subVectors( b, a );
  33. v2.subVectors( point, a );
  34. var dot00 = v0.dot( v0 );
  35. var dot01 = v0.dot( v1 );
  36. var dot02 = v0.dot( v2 );
  37. var dot11 = v1.dot( v1 );
  38. var dot12 = v1.dot( v2 );
  39. var denom = ( dot00 * dot11 - dot01 * dot01 );
  40. var result = optionalTarget || new THREE.Vector3();
  41. // collinear or singular triangle
  42. if ( denom === 0 ) {
  43. // arbitrary location outside of triangle?
  44. // not sure if this is the best idea, maybe should be returning undefined
  45. return result.set( - 2, - 1, - 1 );
  46. }
  47. var invDenom = 1 / denom;
  48. var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
  49. var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
  50. // barycentric coordinates must always sum to 1
  51. return result.set( 1 - u - v, v, u );
  52. };
  53. }();
  54. THREE.Triangle.containsPoint = function () {
  55. var v1 = new THREE.Vector3();
  56. return function ( point, a, b, c ) {
  57. var result = THREE.Triangle.barycoordFromPoint( point, a, b, c, v1 );
  58. return ( result.x >= 0 ) && ( result.y >= 0 ) && ( ( result.x + result.y ) <= 1 );
  59. };
  60. }();
  61. THREE.Triangle.prototype = {
  62. constructor: THREE.Triangle,
  63. set: function ( a, b, c ) {
  64. this.a.copy( a );
  65. this.b.copy( b );
  66. this.c.copy( c );
  67. return this;
  68. },
  69. setFromPointsAndIndices: function ( points, i0, i1, i2 ) {
  70. this.a.copy( points[ i0 ] );
  71. this.b.copy( points[ i1 ] );
  72. this.c.copy( points[ i2 ] );
  73. return this;
  74. },
  75. clone: function () {
  76. return new this.constructor().copy( this );
  77. },
  78. copy: function ( triangle ) {
  79. this.a.copy( triangle.a );
  80. this.b.copy( triangle.b );
  81. this.c.copy( triangle.c );
  82. return this;
  83. },
  84. area: function () {
  85. var v0 = new THREE.Vector3();
  86. var v1 = new THREE.Vector3();
  87. return function () {
  88. v0.subVectors( this.c, this.b );
  89. v1.subVectors( this.a, this.b );
  90. return v0.cross( v1 ).length() * 0.5;
  91. };
  92. }(),
  93. midpoint: function ( optionalTarget ) {
  94. var result = optionalTarget || new THREE.Vector3();
  95. return result.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
  96. },
  97. normal: function ( optionalTarget ) {
  98. return THREE.Triangle.normal( this.a, this.b, this.c, optionalTarget );
  99. },
  100. plane: function ( optionalTarget ) {
  101. var result = optionalTarget || new THREE.Plane();
  102. return result.setFromCoplanarPoints( this.a, this.b, this.c );
  103. },
  104. barycoordFromPoint: function ( point, optionalTarget ) {
  105. return THREE.Triangle.barycoordFromPoint( point, this.a, this.b, this.c, optionalTarget );
  106. },
  107. containsPoint: function ( point ) {
  108. return THREE.Triangle.containsPoint( point, this.a, this.b, this.c );
  109. },
  110. equals: function ( triangle ) {
  111. return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
  112. }
  113. };