Matrix3.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /**
  2. * @author bhouston / http://exocortex.com
  3. */
  4. module( "Matrix3" );
  5. var matrixEquals3 = function( a, b, tolerance ) {
  6. tolerance = tolerance || 0.0001;
  7. if( a.elements.length != b.elements.length ) {
  8. return false;
  9. }
  10. for( var i = 0, il = a.elements.length; i < il; i ++ ) {
  11. var delta = a.elements[i] - b.elements[i];
  12. if( delta > tolerance ) {
  13. return false;
  14. }
  15. }
  16. return true;
  17. };
  18. var toMatrix4 = function( m3 ) {
  19. var result = new THREE.Matrix4();
  20. var re = result.elements;
  21. var me = m3.elements;
  22. re[0] = me[0];
  23. re[1] = me[1];
  24. re[2] = me[2];
  25. re[4] = me[3];
  26. re[5] = me[4];
  27. re[6] = me[5];
  28. re[8] = me[6];
  29. re[9] = me[7];
  30. re[10] = me[8];
  31. return result;
  32. };
  33. test( "constructor", function() {
  34. var a = new THREE.Matrix3();
  35. ok( a.determinant() == 1, "Passed!" );
  36. var b = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
  37. ok( b.elements[0] == 0 );
  38. ok( b.elements[1] == 3 );
  39. ok( b.elements[2] == 6 );
  40. ok( b.elements[3] == 1 );
  41. ok( b.elements[4] == 4 );
  42. ok( b.elements[5] == 7 );
  43. ok( b.elements[6] == 2 );
  44. ok( b.elements[7] == 5 );
  45. ok( b.elements[8] == 8 );
  46. ok( ! matrixEquals3( a, b ), "Passed!" );
  47. });
  48. test( "copy", function() {
  49. var a = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
  50. var b = new THREE.Matrix3().copy( a );
  51. ok( matrixEquals3( a, b ), "Passed!" );
  52. // ensure that it is a true copy
  53. a.elements[0] = 2;
  54. ok( ! matrixEquals3( a, b ), "Passed!" );
  55. });
  56. test( "set", function() {
  57. var b = new THREE.Matrix3();
  58. ok( b.determinant() == 1, "Passed!" );
  59. b.set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
  60. ok( b.elements[0] == 0 );
  61. ok( b.elements[1] == 3 );
  62. ok( b.elements[2] == 6 );
  63. ok( b.elements[3] == 1 );
  64. ok( b.elements[4] == 4 );
  65. ok( b.elements[5] == 7 );
  66. ok( b.elements[6] == 2 );
  67. ok( b.elements[7] == 5 );
  68. ok( b.elements[8] == 8 );
  69. });
  70. test( "identity", function() {
  71. var b = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
  72. ok( b.elements[0] == 0 );
  73. ok( b.elements[1] == 3 );
  74. ok( b.elements[2] == 6 );
  75. ok( b.elements[3] == 1 );
  76. ok( b.elements[4] == 4 );
  77. ok( b.elements[5] == 7 );
  78. ok( b.elements[6] == 2 );
  79. ok( b.elements[7] == 5 );
  80. ok( b.elements[8] == 8 );
  81. var a = new THREE.Matrix3();
  82. ok( ! matrixEquals3( a, b ), "Passed!" );
  83. b.identity();
  84. ok( matrixEquals3( a, b ), "Passed!" );
  85. });
  86. test( "multiplyScalar", function() {
  87. var b = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
  88. ok( b.elements[0] == 0 );
  89. ok( b.elements[1] == 3 );
  90. ok( b.elements[2] == 6 );
  91. ok( b.elements[3] == 1 );
  92. ok( b.elements[4] == 4 );
  93. ok( b.elements[5] == 7 );
  94. ok( b.elements[6] == 2 );
  95. ok( b.elements[7] == 5 );
  96. ok( b.elements[8] == 8 );
  97. b.multiplyScalar( 2 );
  98. ok( b.elements[0] == 0*2 );
  99. ok( b.elements[1] == 3*2 );
  100. ok( b.elements[2] == 6*2 );
  101. ok( b.elements[3] == 1*2 );
  102. ok( b.elements[4] == 4*2 );
  103. ok( b.elements[5] == 7*2 );
  104. ok( b.elements[6] == 2*2 );
  105. ok( b.elements[7] == 5*2 );
  106. ok( b.elements[8] == 8*2 );
  107. });
  108. test( "determinant", function() {
  109. var a = new THREE.Matrix3();
  110. ok( a.determinant() == 1, "Passed!" );
  111. a.elements[0] = 2;
  112. ok( a.determinant() == 2, "Passed!" );
  113. a.elements[0] = 0;
  114. ok( a.determinant() == 0, "Passed!" );
  115. // calculated via http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/threeD/index.htm
  116. a.set( 2, 3, 4, 5, 13, 7, 8, 9, 11 );
  117. ok( a.determinant() == -73, "Passed!" );
  118. });
  119. test( "getInverse", function() {
  120. var identity = new THREE.Matrix4();
  121. var a = new THREE.Matrix4();
  122. var b = new THREE.Matrix3().set( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
  123. var c = new THREE.Matrix4().set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
  124. ok( ! matrixEquals3( a, b ), "Passed!" );
  125. b.getInverse( a, false );
  126. ok( matrixEquals3( b, new THREE.Matrix3() ), "Passed!" );
  127. try {
  128. b.getInverse( c, true );
  129. ok( false, "Passed!" ); // should never get here.
  130. }
  131. catch( err ) {
  132. ok( true, "Passed!" );
  133. }
  134. var testMatrices = [
  135. new THREE.Matrix4().makeRotationX( 0.3 ),
  136. new THREE.Matrix4().makeRotationX( -0.3 ),
  137. new THREE.Matrix4().makeRotationY( 0.3 ),
  138. new THREE.Matrix4().makeRotationY( -0.3 ),
  139. new THREE.Matrix4().makeRotationZ( 0.3 ),
  140. new THREE.Matrix4().makeRotationZ( -0.3 ),
  141. new THREE.Matrix4().makeScale( 1, 2, 3 ),
  142. new THREE.Matrix4().makeScale( 1/8, 1/2, 1/3 )
  143. ];
  144. for( var i = 0, il = testMatrices.length; i < il; i ++ ) {
  145. var m = testMatrices[i];
  146. var mInverse3 = new THREE.Matrix3().getInverse( m );
  147. var mInverse = toMatrix4( mInverse3 );
  148. // the determinant of the inverse should be the reciprocal
  149. ok( Math.abs( m.determinant() * mInverse3.determinant() - 1 ) < 0.0001, "Passed!" );
  150. ok( Math.abs( m.determinant() * mInverse.determinant() - 1 ) < 0.0001, "Passed!" );
  151. var mProduct = new THREE.Matrix4().multiplyMatrices( m, mInverse );
  152. ok( Math.abs( mProduct.determinant() - 1 ) < 0.0001, "Passed!" );
  153. ok( matrixEquals3( mProduct, identity ), "Passed!" );
  154. }
  155. });
  156. test( "transpose", function() {
  157. var a = new THREE.Matrix3();
  158. var b = a.clone().transpose();
  159. ok( matrixEquals3( a, b ), "Passed!" );
  160. b = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
  161. var c = b.clone().transpose();
  162. ok( ! matrixEquals3( b, c ), "Passed!" );
  163. c.transpose();
  164. ok( matrixEquals3( b, c ), "Passed!" );
  165. });
  166. test( "clone", function() {
  167. var a = new THREE.Matrix3().set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
  168. var b = a.clone();
  169. ok( matrixEquals3( a, b ), "Passed!" );
  170. // ensure that it is a true copy
  171. a.elements[0] = 2;
  172. ok( ! matrixEquals3( a, b ), "Passed!" );
  173. });