3x3矩阵类

   1:  package com.jme.math;
   2:   
   3:  import java.io.IOException;
   4:  import java.io.Serializable;
   5:  import java.nio.FloatBuffer;
   6:  import java.util.logging.Logger;
   7:   
   8:  import com.jme.system.JmeException;
   9:  import com.jme.util.export.InputCapsule;
  10:  import com.jme.util.export.JMEExporter;
  11:  import com.jme.util.export.JMEImporter;
  12:  import com.jme.util.export.OutputCapsule;
  13:  import com.jme.util.export.Savable;
  14:  import com.jme.util.geom.BufferUtils;
  15:   
  16:  /**
  17:   * Matrix3f defines a 3x3 matrix. Matrix data is maintained
  18:   * internally and is accessible via the get and set methods. Convenience methods
  19:   * are used for matrix operations as well as generating a matrix from a given
  20:   * set of values.
  21:   * 3X3矩阵类
  22:   * 
  23:   * @author Mark Powell
  24:   * @author Joshua Slack
  25:   */
  26:  public class Matrix3f implements Serializable, Savable, Cloneable {
  27:      private static final Logger logger = Logger.getLogger(Matrix3f.class
  28:              .getName());
  29:   
  30:      private static final long serialVersionUID = 1L;
  31:   
  32:      public float m00, m01, m02;
  33:      public float m10, m11, m12;
  34:      public float m20, m21, m22;
  35:   
  36:      /**
  37:       * Constructor instantiates a new Matrix3f object. The initial
  38:       * values for the matrix is that of the identity matrix.
  39:       * 默认构造单位矩阵
  40:       * 
  41:       */
  42:      public Matrix3f() {
  43:          loadIdentity();
  44:      }
  45:   
  46:      /**
  47:       * constructs a matrix with the given values.
  48:       * 
  49:       * @param m00
  50:       *            0x0 in the matrix.
  51:       * @param m01
  52:       *            0x1 in the matrix.
  53:       * @param m02
  54:       *            0x2 in the matrix.
  55:       * @param m10
  56:       *            1x0 in the matrix.
  57:       * @param m11
  58:       *            1x1 in the matrix.
  59:       * @param m12
  60:       *            1x2 in the matrix.
  61:       * @param m20
  62:       *            2x0 in the matrix.
  63:       * @param m21
  64:       *            2x1 in the matrix.
  65:       * @param m22
  66:       *            2x2 in the matrix.
  67:       */
  68:      public Matrix3f(float m00, float m01, float m02, float m10, float m11,
  69:              float m12, float m20, float m21, float m22) {
  70:   
  71:          this.m00 = m00;
  72:          this.m01 = m01;
  73:          this.m02 = m02;
  74:          this.m10 = m10;
  75:          this.m11 = m11;
  76:          this.m12 = m12;
  77:          this.m20 = m20;
  78:          this.m21 = m21;
  79:          this.m22 = m22;
  80:      }
  81:   
  82:      /**
  83:       * Copy constructor that creates a new Matrix3f object that is
  84:       * the same as the provided matrix.
  85:       * 
  86:       * @param mat
  87:       *            the matrix to copy.
  88:       */
  89:      public Matrix3f(Matrix3f mat) {
  90:          copy(mat);
  91:      }
  92:   
  93:      /**
  94:       * copy transfers the contents of a given matrix to this
  95:       * matrix. If a null matrix is supplied, this matrix is set to the identity
  96:       * matrix.
  97:       * 
  98:       * @param matrix
  99:       *            the matrix to copy.
 100:       */
 101:      public void copy(Matrix3f matrix) {
 102:          if (null == matrix) {
 103:              loadIdentity();
 104:          } else {
 105:              m00 = matrix.m00;
 106:              m01 = matrix.m01;
 107:              m02 = matrix.m02;
 108:              m10 = matrix.m10;
 109:              m11 = matrix.m11;
 110:              m12 = matrix.m12;
 111:              m20 = matrix.m20;
 112:              m21 = matrix.m21;
 113:              m22 = matrix.m22;
 114:          }
 115:      }
 116:   
 117:      /**
 118:       * get retrieves a value from the matrix at the given position.
 119:       * If the position is invalid a JmeException is thrown.
 120:       * 获取指定位置的元素值
 121:       * 
 122:       * @param i
 123:       *            the row index.行索引(取值范围:0、1、2)
 124:       * @param j
 125:       *            the colum index.列索引(取值范围:0、1、2)
 126:       * @return the value at (i, j).
 127:       */
 128:      public float get(int i, int j) {
 129:          switch (i) {
 130:          case 0:
 131:              switch (j) {
 132:              case 0:
 133:                  return m00;
 134:              case 1:
 135:                  return m01;
 136:              case 2:
 137:                  return m02;
 138:              }
 139:          case 1:
 140:              switch (j) {
 141:              case 0:
 142:                  return m10;
 143:              case 1:
 144:                  return m11;
 145:              case 2:
 146:                  return m12;
 147:              }
 148:          case 2:
 149:              switch (j) {
 150:              case 0:
 151:                  return m20;
 152:              case 1:
 153:                  return m21;
 154:              case 2:
 155:                  return m22;
 156:              }
 157:          }
 158:   
 159:          logger.warning("Invalid matrix index.");
 160:          throw new JmeException("Invalid indices into matrix.");
 161:      }
 162:   
 163:      /**
 164:       * get(float[]) returns the matrix in row-major or column-major
 165:       * order.
 166:       * 将矩阵按行或列的顺序存入参数data数组中
 167:       * 
 168:       * @param data
 169:       *            The array to return the data into. This array can be 9 or 16
 170:       *            floats in size. Only the upper 3x3 are assigned to in the case
 171:       *            of a 16 element array.
 172:       * @param rowMajor
 173:       *            True for row major storage in the array (translation in
 174:       *            elements 3, 7, 11 for a 4x4), false for column major
 175:       *            (translation in elements 12, 13, 14 for a 4x4).
 176:       */
 177:      public void get(float[] data, boolean rowMajor) {
 178:          if (data.length == 9) {
 179:              if (rowMajor) {
 180:                  data[0] = m00;
 181:                  data[1] = m01;
 182:                  data[2] = m02;
 183:                  data[3] = m10;
 184:                  data[4] = m11;
 185:                  data[5] = m12;
 186:                  data[6] = m20;
 187:                  data[7] = m21;
 188:                  data[8] = m22;
 189:              } else {
 190:                  data[0] = m00;
 191:                  data[1] = m10;
 192:                  data[2] = m20;
 193:                  data[3] = m01;
 194:                  data[4] = m11;
 195:                  data[5] = m21;
 196:                  data[6] = m02;
 197:                  data[7] = m12;
 198:                  data[8] = m22;
 199:              }
 200:          } else if (data.length == 16) {
 201:              if (rowMajor) {
 202:                  data[0] = m00;
 203:                  data[1] = m01;
 204:                  data[2] = m02;
 205:                  data[4] = m10;
 206:                  data[5] = m11;
 207:                  data[6] = m12;
 208:                  data[8] = m20;
 209:                  data[9] = m21;
 210:                  data[10] = m22;
 211:              } else {
 212:                  data[0] = m00;
 213:                  data[1] = m10;
 214:                  data[2] = m20;
 215:                  data[4] = m01;
 216:                  data[5] = m11;
 217:                  data[6] = m21;
 218:                  data[8] = m02;
 219:                  data[9] = m12;
 220:                  data[10] = m22;
 221:              }
 222:          } else {
 223:              throw new JmeException(
 224:                      "Array size must be 9 or 16 in Matrix3f.get().");
 225:          }
 226:      }
 227:   
 228:      /**
 229:       * getColumn returns one of three columns specified by the
 230:       * parameter. This column is returned as a Vector3f object.
 231:       * 获取指定列构造的向量
 232:       * 
 233:       * @param i
 234:       *            the column to retrieve. Must be between 0 and 2.
 235:       * @return the column specified by the index.
 236:       */
 237:      public Vector3f getColumn(int i) {
 238:          return getColumn(i, null);
 239:      }
 240:   
 241:      /**
 242:       * getColumn returns one of three columns specified by the
 243:       * parameter. This column is returned as a Vector3f object.
 244:       * 获取指定列构造的向量
 245:       * 
 246:       * @param i
 247:       *            the column to retrieve. Must be between 0 and 2.
 248:       * @param store
 249:       *            the vector object to store the result in. if null, a new one
 250:       *            is created.
 251:       * @return the column specified by the index.
 252:       */
 253:      public Vector3f getColumn(int i, Vector3f store) {
 254:          if (store == null)
 255:              store = new Vector3f();
 256:          switch (i) {
 257:          case 0:
 258:              store.x = m00;
 259:              store.y = m10;
 260:              store.z = m20;
 261:              break;
 262:          case 1:
 263:              store.x = m01;
 264:              store.y = m11;
 265:              store.z = m21;
 266:              break;
 267:          case 2:
 268:              store.x = m02;
 269:              store.y = m12;
 270:              store.z = m22;
 271:              break;
 272:          default:
 273:              logger.warning("Invalid column index.");
 274:              throw new JmeException("Invalid column index. " + i);
 275:          }
 276:          return store;
 277:      }
 278:   
 279:      /**
 280:       * getColumn returns one of three rows as specified by the
 281:       * parameter. This row is returned as a Vector3f object.
 282:       * 获取指定行构造的向量
 283:       * 
 284:       * @param i
 285:       *            the row to retrieve. Must be between 0 and 2.
 286:       * @return the row specified by the index.
 287:       */
 288:      public Vector3f getRow(int i) {
 289:          return getRow(i, null);
 290:      }
 291:   
 292:      /**
 293:       * getRow returns one of three rows as specified by the
 294:       * parameter. This row is returned as a Vector3f object. 
 295:       * 获取指定行构造的向量
 296:       * 
 297:       * @param i
 298:       *            the row to retrieve. Must be between 0 and 2.
 299:       * @param store
 300:       *            the vector object to store the result in. if null, a new one
 301:       *            is created.
 302:       * @return the row specified by the index.
 303:       */
 304:      public Vector3f getRow(int i, Vector3f store) {
 305:          if (store == null)
 306:              store = new Vector3f();
 307:          switch (i) {
 308:          case 0:
 309:              store.x = m00;
 310:              store.y = m01;
 311:              store.z = m02;
 312:              break;
 313:          case 1:
 314:              store.x = m10;
 315:              store.y = m11;
 316:              store.z = m12;
 317:              break;
 318:          case 2:
 319:              store.x = m20;
 320:              store.y = m21;
 321:              store.z = m22;
 322:              break;
 323:          default:
 324:              logger.warning("Invalid row index.");
 325:              throw new JmeException("Invalid row index. " + i);
 326:          }
 327:          return store;
 328:      }
 329:   
 330:      /**
 331:       * toFloatBuffer returns a FloatBuffer object that contains the
 332:       * matrix data.
 333:       * 
 334:       * @return matrix data as a FloatBuffer.
 335:       */
 336:      public FloatBuffer toFloatBuffer() {
 337:          FloatBuffer fb = BufferUtils.createFloatBuffer(9);
 338:   
 339:          fb.put(m00).put(m01).put(m02);
 340:          fb.put(m10).put(m11).put(m12);
 341:          fb.put(m20).put(m21).put(m22);
 342:          fb.rewind();
 343:          return fb;
 344:      }
 345:   
 346:      /**
 347:       * fillFloatBuffer fills a FloatBuffer object with the matrix
 348:       * data.
 349:       * 
 350:       * @param fb
 351:       *            the buffer to fill, starting at current position. Must have
 352:       *            room for 9 more floats.
 353:       * @return matrix data as a FloatBuffer. (position is advanced by 9 and any
 354:       *         limit set is not changed).
 355:       */
 356:      public FloatBuffer fillFloatBuffer(FloatBuffer fb) {
 357:          fb.put(m00).put(m01).put(m02);
 358:          fb.put(m10).put(m11).put(m12);
 359:          fb.put(m20).put(m21).put(m22);
 360:          return fb;
 361:      }
 362:   
 363:      /**
 364:       * 
 365:       * setColumn sets a particular column of this matrix to that
 366:       * represented by the provided vector.
 367:       * 根据给定列向量设置矩阵的列
 368:       * 
 369:       * @param i
 370:       *            the column to set.
 371:       * @param column
 372:       *            the data to set.
 373:       */
 374:      public void setColumn(int i, Vector3f column) {
 375:   
 376:          if (column == null) {
 377:              logger.warning("Column is null. Ignoring.");
 378:              return;
 379:          }
 380:          switch (i) {
 381:          case 0:
 382:              m00 = column.x;
 383:              m10 = column.y;
 384:              m20 = column.z;
 385:              break;
 386:          case 1:
 387:              m01 = column.x;
 388:              m11 = column.y;
 389:              m21 = column.z;
 390:              break;
 391:          case 2:
 392:              m02 = column.x;
 393:              m12 = column.y;
 394:              m22 = column.z;
 395:              break;
 396:          default:
 397:              logger.warning("Invalid column index.");
 398:              throw new JmeException("Invalid column index. " + i);
 399:          }
 400:      }
 401:   
 402:      /**
 403:       * 
 404:       * setRow sets a particular row of this matrix to that
 405:       * represented by the provided vector.
 406:       * 根据给定行向量设置矩阵的行
 407:       * 
 408:       * @param i
 409:       *            the row to set.
 410:       * @param row
 411:       *            the data to set.
 412:       */
 413:      public void setRow(int i, Vector3f row) {
 414:   
 415:          if (row == null) {
 416:              logger.warning("Row is null. Ignoring.");
 417:              return;
 418:          }
 419:          switch (i) {
 420:          case 0:
 421:              m00 = row.x;
 422:              m01 = row.y;
 423:              m02 = row.z;
 424:              break;
 425:          case 1:
 426:              m10 = row.x;
 427:              m11 = row.y;
 428:              m12 = row.z;
 429:              break;
 430:          case 2:
 431:              m20 = row.x;
 432:              m21 = row.y;
 433:              m22 = row.z;
 434:              break;
 435:          default:
 436:              logger.warning("Invalid row index.");
 437:              throw new JmeException("Invalid row index. " + i);
 438:          }
 439:      }
 440:   
 441:      /**
 442:       * set places a given value into the matrix at the given
 443:       * position. If the position is invalid a JmeException is
 444:       * thrown.
 445:       * 设定某位置的值
 446:       * 
 447:       * @param i
 448:       *            the row index.
 449:       * @param j
 450:       *            the colum index.
 451:       * @param value
 452:       *            the value for (i, j).
 453:       */
 454:      public void set(int i, int j, float value) {
 455:          switch (i) {
 456:          case 0:
 457:              switch (j) {
 458:              case 0:
 459:                  m00 = value;
 460:                  return;
 461:              case 1:
 462:                  m01 = value;
 463:                  return;
 464:              case 2:
 465:                  m02 = value;
 466:                  return;
 467:              }
 468:          case 1:
 469:              switch (j) {
 470:              case 0:
 471:                  m10 = value;
 472:                  return;
 473:              case 1:
 474:                  m11 = value;
 475:                  return;
 476:              case 2:
 477:                  m12 = value;
 478:                  return;
 479:              }
 480:          case 2:
 481:              switch (j) {
 482:              case 0:
 483:                  m20 = value;
 484:                  return;
 485:              case 1:
 486:                  m21 = value;
 487:                  return;
 488:              case 2:
 489:                  m22 = value;
 490:                  return;
 491:              }
 492:          }
 493:   
 494:          logger.warning("Invalid matrix index.");
 495:          throw new JmeException("Invalid indices into matrix.");
 496:      }
 497:   
 498:      /**
 499:       * 
 500:       * set sets the values of the matrix to those supplied by the
 501:       * 3x3 two dimenion array.
 502:       * 用二维数组设置矩阵各元素值
 503:       * 
 504:       * @param matrix
 505:       *            the new values of the matrix.
 506:       * @throws JmeException
 507:       *             if the array is not of size 9.
 508:       */
 509:      public void set(float[][] matrix) {
 510:          if (matrix.length != 3 || matrix[0].length != 3) {
 511:              throw new JmeException("Array must be of size 9.");
 512:          }
 513:   
 514:          m00 = matrix[0][0];
 515:          m01 = matrix[0][1];
 516:          m02 = matrix[0][2];
 517:          m10 = matrix[1][0];
 518:          m11 = matrix[1][1];
 519:          m12 = matrix[1][2];
 520:          m20 = matrix[2][0];
 521:          m21 = matrix[2][1];
 522:          m22 = matrix[2][2];
 523:      }
 524:   
 525:      /**
 526:       * Recreate Matrix using the provided axis.
 527:       * 根据给定各列向量构造矩阵
 528:       * 
 529:       * @param uAxis
 530:       *            Vector3f
 531:       * @param vAxis
 532:       *            Vector3f
 533:       * @param wAxis
 534:       *            Vector3f
 535:       */
 536:      public void fromAxes(Vector3f uAxis, Vector3f vAxis, Vector3f wAxis) {
 537:          m00 = uAxis.x;
 538:          m10 = uAxis.y;
 539:          m20 = uAxis.z;
 540:   
 541:          m01 = vAxis.x;
 542:          m11 = vAxis.y;
 543:          m21 = vAxis.z;
 544:   
 545:          m02 = wAxis.x;
 546:          m12 = wAxis.y;
 547:          m22 = wAxis.z;
 548:      }
 549:   
 550:      /**
 551:       * set sets the values of this matrix from an array of values
 552:       * assuming that the data is rowMajor order;
 553:       * 根据给定数组按行设置矩阵
 554:       * 
 555:       * @param matrix
 556:       *            the matrix to set the value to.
 557:       */
 558:      public void set(float[] matrix) {
 559:          set(matrix, true);
 560:      }
 561:   
 562:      /**
 563:       * set sets the values of this matrix from an array of values;
 564:       * 根据给定数组按行或列设置矩阵
 565:       * 
 566:       * @param matrix
 567:       *            the matrix to set the value to.
 568:       * @param rowMajor
 569:       *            whether the incoming data is in row or column major order.
 570:       */
 571:      public void set(float[] matrix, boolean rowMajor) {
 572:          if (matrix.length != 9)
 573:              throw new JmeException("Array must be of size 9.");
 574:   
 575:          if (rowMajor) {
 576:              m00 = matrix[0];
 577:              m01 = matrix[1];
 578:              m02 = matrix[2];
 579:              m10 = matrix[3];
 580:              m11 = matrix[4];
 581:              m12 = matrix[5];
 582:              m20 = matrix[6];
 583:              m21 = matrix[7];
 584:              m22 = matrix[8];
 585:          } else {
 586:              m00 = matrix[0];
 587:              m01 = matrix[3];
 588:              m02 = matrix[6];
 589:              m10 = matrix[1];
 590:              m11 = matrix[4];
 591:              m12 = matrix[7];
 592:              m20 = matrix[2];
 593:              m21 = matrix[5];
 594:              m22 = matrix[8];
 595:          }
 596:      }
 597:   
 598:      /**
 599:       * 
 600:       * set defines the values of the matrix based on a supplied
 601:       * Quaternion. It should be noted that all previous values will
 602:       * be overridden.
 603:       * 四元数构造旋转矩阵
 604:       * 
 605:       * @param quaternion
 606:       *            the quaternion to create a rotational matrix from.
 607:       */
 608:      public void set(Quaternion quaternion) {
 609:          quaternion.toRotationMatrix(this);
 610:      }
 611:   
 612:      /**
 613:       * loadIdentity sets this matrix to the identity matrix. Where
 614:       * all values are zero except those along the diagonal which are one.
 615:       * 单位矩阵
 616:       * 
 617:       */
 618:      public void loadIdentity() {
 619:          m01 = m02 = m10 = m12 = m20 = m21 = 0;
 620:          m00 = m11 = m22 = 1;
 621:      }
 622:   
 623:      /**
 624:       * 是否单位矩阵
 625:       * 
 626:       * @return true if this matrix is identity
 627:       */
 628:      public boolean isIdentity() {
 629:          return (m00 == 1 && m01 == 0 && m02 == 0)
 630:                  && (m10 == 0 && m11 == 1 && m12 == 0)
 631:                  && (m20 == 0 && m21 == 0 && m22 == 1);
 632:      }
 633:   
 634:      /**
 635:       * fromAngleAxis sets this matrix4f to the values specified by
 636:       * an angle and an axis of rotation. This method creates an object, so use
 637:       * fromAngleNormalAxis if your axis is already normalized.
 638:       * 绕轴axis(非单位向量)旋转angle(弧度)角的3D旋转矩阵
 639:       * 
 640:       * @param angle
 641:       *            the angle to rotate (in radians).
 642:       * @param axis
 643:       *            the axis of rotation.
 644:       */
 645:      public void fromAngleAxis(float angle, Vector3f axis) {
 646:          Vector3f normAxis = axis.normalize();
 647:          fromAngleNormalAxis(angle, normAxis);
 648:      }
 649:   
 650:      /**
 651:       * fromAngleNormalAxis sets this matrix4f to the values
 652:       * specified by an angle and a normalized axis of rotation.
 653:       * 绕轴axis(单位向量)旋转angle(弧度)角的3D旋转矩阵
 654:       * 
 655:       * @param angle
 656:       *            the angle to rotate (in radians).
 657:       * @param axis
 658:       *            the axis of rotation (already normalized).
 659:       */
 660:      public void fromAngleNormalAxis(float angle, Vector3f axis) {
 661:          float fCos = FastMath.cos(angle);
 662:          float fSin = FastMath.sin(angle);
 663:          float fOneMinusCos = ((float) 1.0) - fCos;
 664:          float fX2 = axis.x * axis.x;
 665:          float fY2 = axis.y * axis.y;
 666:          float fZ2 = axis.z * axis.z;
 667:          float fXYM = axis.x * axis.y * fOneMinusCos;
 668:          float fXZM = axis.x * axis.z * fOneMinusCos;
 669:          float fYZM = axis.y * axis.z * fOneMinusCos;
 670:          float fXSin = axis.x * fSin;
 671:          float fYSin = axis.y * fSin;
 672:          float fZSin = axis.z * fSin;
 673:   
 674:          m00 = fX2 * fOneMinusCos + fCos;
 675:          m01 = fXYM - fZSin;
 676:          m02 = fXZM + fYSin;
 677:          m10 = fXYM + fZSin;
 678:          m11 = fY2 * fOneMinusCos + fCos;
 679:          m12 = fYZM - fXSin;
 680:          m20 = fXZM - fYSin;
 681:          m21 = fYZM + fXSin;
 682:          m22 = fZ2 * fOneMinusCos + fCos;
 683:      }
 684:   
 685:      /**
 686:       * mult multiplies this matrix by a given matrix. The result
 687:       * matrix is returned as a new object. If the given matrix is null, a null
 688:       * matrix is returned.
 689:       * 矩阵乘法
 690:       * 
 691:       * @param mat
 692:       *            the matrix to multiply this matrix by.
 693:       * @return the result matrix.
 694:       */
 695:      public Matrix3f mult(Matrix3f mat) {
 696:          return mult(mat, null);
 697:      }
 698:   
 699:      /**
 700:       * mult multiplies this matrix by a given matrix. The result
 701:       * matrix is returned as a new object.
 702:       * 矩阵乘法,结果存入参数product中
 703:       * 
 704:       * @param mat
 705:       *            the matrix to multiply this matrix by.
 706:       * @param product
 707:       *            the matrix to store the result in. if null, a new matrix3f is
 708:       *            created. It is safe for mat and product to be the same object.
 709:       * @return a matrix3f object containing the result of this operation
 710:       */
 711:      public Matrix3f mult(Matrix3f mat, Matrix3f product) {
 712:   
 713:          float temp00, temp01, temp02;
 714:          float temp10, temp11, temp12;
 715:          float temp20, temp21, temp22;
 716:   
 717:          if (product == null)
 718:              product = new Matrix3f();
 719:          temp00 = m00 * mat.m00 + m01 * mat.m10 + m02 * mat.m20;
 720:          temp01 = m00 * mat.m01 + m01 * mat.m11 + m02 * mat.m21;
 721:          temp02 = m00 * mat.m02 + m01 * mat.m12 + m02 * mat.m22;
 722:          temp10 = m10 * mat.m00 + m11 * mat.m10 + m12 * mat.m20;
 723:          temp11 = m10 * mat.m01 + m11 * mat.m11 + m12 * mat.m21;
 724:          temp12 = m10 * mat.m02 + m11 * mat.m12 + m12 * mat.m22;
 725:          temp20 = m20 * mat.m00 + m21 * mat.m10 + m22 * mat.m20;
 726:          temp21 = m20 * mat.m01 + m21 * mat.m11 + m22 * mat.m21;
 727:          temp22 = m20 * mat.m02 + m21 * mat.m12 + m22 * mat.m22;
 728:   
 729:          product.m00 = temp00;
 730:          product.m01 = temp01;
 731:          product.m02 = temp02;
 732:          product.m10 = temp10;
 733:          product.m11 = temp11;
 734:          product.m12 = temp12;
 735:          product.m20 = temp20;
 736:          product.m21 = temp21;
 737:          product.m22 = temp22;
 738:   
 739:          return product;
 740:      }
 741:   
 742:      /**
 743:       * mult multiplies this matrix by a given Vector3f
 744:       * object. The result vector is returned. If the given vector is null, null
 745:       * will be returned.
 746:       * 矩阵乘以向量
 747:       * 
 748:       * @param vec
 749:       *            the vector to multiply this matrix by.
 750:       * @return the result vector.
 751:       */
 752:      public Vector3f mult(Vector3f vec) {
 753:          return mult(vec, null);
 754:      }
 755:   
 756:      /**
 757:       * Multiplies this 3x3 matrix by the 1x3 Vector vec and stores the result in
 758:       * product.
 759:       * 矩阵乘以向量,结果存入参数product中
 760:       * 
 761:       * @param vec
 762:       *            The Vector3f to multiply.
 763:       * @param product
 764:       *            The Vector3f to store the result, it is safe for this to be
 765:       *            the same as vec.
 766:       * @return The given product vector.
 767:       */
 768:      public Vector3f mult(Vector3f vec, Vector3f product) {
 769:   
 770:          if (null == product) {
 771:              product = new Vector3f();
 772:          }
 773:   
 774:          float x = vec.x;
 775:          float y = vec.y;
 776:          float z = vec.z;
 777:   
 778:          product.x = m00 * x + m01 * y + m02 * z;
 779:          product.y = m10 * x + m11 * y + m12 * z;
 780:          product.z = m20 * x + m21 * y + m22 * z;
 781:          return product;
 782:      }
 783:   
 784:      /**
 785:       * multLocal multiplies this matrix internally by a given float
 786:       * scale factor.
 787:       * 矩阵标量乘
 788:       * 
 789:       * @param scale
 790:       *            the value to scale by.
 791:       * @return this Matrix3f
 792:       */
 793:      public Matrix3f multLocal(float scale) {
 794:          m00 *= scale;
 795:          m01 *= scale;
 796:          m02 *= scale;
 797:          m10 *= scale;
 798:          m11 *= scale;
 799:          m12 *= scale;
 800:          m20 *= scale;
 801:          m21 *= scale;
 802:          m22 *= scale;
 803:          return this;
 804:      }
 805:   
 806:      /**
 807:       * multLocal multiplies this matrix by a given
 808:       * Vector3f object. The result vector is stored inside the
 809:       * passed vector, then returned . If the given vector is null, null will be
 810:       * returned.
 811:       * 矩阵乘向量
 812:       * 
 813:       * @param vec
 814:       *            the vector to multiply this matrix by.
 815:       * @return The passed vector after multiplication
 816:       */
 817:      public Vector3f multLocal(Vector3f vec) {
 818:          if (vec == null)
 819:              return null;
 820:          float x = vec.x;
 821:          float y = vec.y;
 822:          vec.x = m00 * x + m01 * y + m02 * vec.z;
 823:          vec.y = m10 * x + m11 * y + m12 * vec.z;
 824:          vec.z = m20 * x + m21 * y + m22 * vec.z;
 825:          return vec;
 826:      }
 827:   
 828:      /**
 829:       * mult multiplies this matrix by a given matrix. The result
 830:       * matrix is saved in the current matrix. If the given matrix is null,
 831:       * nothing happens. The current matrix is returned. This is equivalent to
 832:       * this*=mat
 833:       * 矩阵乘以矩阵
 834:       * 
 835:       * @param mat
 836:       *            the matrix to multiply this matrix by.
 837:       * @return This matrix, after the multiplication
 838:       */
 839:      public Matrix3f multLocal(Matrix3f mat) {
 840:   
 841:          return mult(mat, this);
 842:      }
 843:   
 844:      /**
 845:       * Transposes this matrix in place. Returns this matrix for chaining
 846:       * 转置矩阵
 847:       * 
 848:       * @return This matrix after transpose
 849:       */
 850:      public Matrix3f transposeLocal() {
 851:          float[] tmp = new float[9];
 852:          get(tmp, false);
 853:          set(tmp, true);
 854:          return this;
 855:      }
 856:   
 857:      /**
 858:       * Inverts this matrix as a new Matrix3f. 
 859:       * 逆矩阵,不改变自身
 860:       * 
 861:       * @return The new inverse matrix
 862:       */
 863:      public Matrix3f invert() {
 864:          return invert(null);
 865:      }
 866:   
 867:      /**
 868:       * Inverts this matrix and stores it in the given store.
 869:       * 逆矩阵,保存在参数中,不改变自身
 870:       * 
 871:       * @return The store
 872:       */
 873:      public Matrix3f invert(Matrix3f store) {
 874:          if (store == null)
 875:              store = new Matrix3f();
 876:   
 877:          float det = determinant();
 878:          if (FastMath.abs(det) <= 0)
 879:              return store.zero();
 880:   
 881:          store.m00 = m11 * m22 - m12 * m21;
 882:          store.m01 = m02 * m21 - m01 * m22;
 883:          store.m02 = m01 * m12 - m02 * m11;
 884:          store.m10 = m12 * m20 - m10 * m22;
 885:          store.m11 = m00 * m22 - m02 * m20;
 886:          store.m12 = m02 * m10 - m00 * m12;
 887:          store.m20 = m10 * m21 - m11 * m20;
 888:          store.m21 = m01 * m20 - m00 * m21;
 889:          store.m22 = m00 * m11 - m01 * m10;
 890:   
 891:          store.multLocal(1f / det);
 892:          return store;
 893:      }
 894:   
 895:      /**
 896:       * Inverts this matrix locally.
 897:       * 逆矩阵,改变自身
 898:       * 
 899:       * @return this
 900:       */
 901:      public Matrix3f invertLocal() {
 902:          float det = determinant();
 903:          if (FastMath.abs(det) <= FastMath.FLT_EPSILON)
 904:              return zero();
 905:   
 906:          float f00 = m11 * m22 - m12 * m21;
 907:          float f01 = m02 * m21 - m01 * m22;
 908:          float f02 = m01 * m12 - m02 * m11;
 909:          float f10 = m12 * m20 - m10 * m22;
 910:          float f11 = m00 * m22 - m02 * m20;
 911:          float f12 = m02 * m10 - m00 * m12;
 912:          float f20 = m10 * m21 - m11 * m20;
 913:          float f21 = m01 * m20 - m00 * m21;
 914:          float f22 = m00 * m11 - m01 * m10;
 915:   
 916:          m00 = f00;
 917:          m01 = f01;
 918:          m02 = f02;
 919:          m10 = f10;
 920:          m11 = f11;
 921:          m12 = f12;
 922:          m20 = f20;
 923:          m21 = f21;
 924:          m22 = f22;
 925:   
 926:          multLocal(1f / det);
 927:          return this;
 928:      }
 929:   
 930:      /**
 931:       * Returns a new matrix representing the adjoint of this matrix.
 932:       * 伴随矩阵
 933:       * 
 934:       * @return The adjoint matrix
 935:       */
 936:      public Matrix3f adjoint() {
 937:          return adjoint(null);
 938:      }
 939:   
 940:      /**
 941:       * Places the adjoint of this matrix in store (creates store if null.)
 942:       * 伴随矩阵
 943:       * 
 944:       * @param store
 945:       *            The matrix to store the result in. If null, a new matrix is
 946:       *            created.
 947:       * @return store
 948:       */
 949:      public Matrix3f adjoint(Matrix3f store) {
 950:          if (store == null)
 951:              store = new Matrix3f();
 952:   
 953:          store.m00 = m11 * m22 - m12 * m21;
 954:          store.m01 = m02 * m21 - m01 * m22;
 955:          store.m02 = m01 * m12 - m02 * m11;
 956:          store.m10 = m12 * m20 - m10 * m22;
 957:          store.m11 = m00 * m22 - m02 * m20;
 958:          store.m12 = m02 * m10 - m00 * m12;
 959:          store.m20 = m10 * m21 - m11 * m20;
 960:          store.m21 = m01 * m20 - m00 * m21;
 961:          store.m22 = m00 * m11 - m01 * m10;
 962:   
 963:          return store;
 964:      }
 965:   
 966:      /**
 967:       * determinant generates the determinate of this matrix.
 968:       * 矩阵的行列式
 969:       * 
 970:       * @return the determinate
 971:       */
 972:      public float determinant() {
 973:          float fCo00 = m11 * m22 - m12 * m21;
 974:          float fCo10 = m12 * m20 - m10 * m22;
 975:          float fCo20 = m10 * m21 - m11 * m20;
 976:          float fDet = m00 * fCo00 + m01 * fCo10 + m02 * fCo20;
 977:          return fDet;
 978:      }
 979:   
 980:      /**
 981:       * Sets all of the values in this matrix to zero.
 982:       * 重置矩阵,各元素置为0
 983:       * 
 984:       * @return this matrix
 985:       */
 986:      public Matrix3f zero() {
 987:          m00 = m01 = m02 = m10 = m11 = m12 = m20 = m21 = m22 = 0.0f;
 988:          return this;
 989:      }
 990:   
 991:      /**
 992:       * add adds the values of a parameter matrix to this matrix.
 993:       * 矩阵加法
 994:       * 
 995:       * @param mat
 996:       *            the matrix to add to this.
 997:       */
 998:      public void add(Matrix3f mat) {
 999:          m00 += mat.m00;
1000:          m01 += mat.m01;
1001:          m02 += mat.m02;
1002:          m10 += mat.m10;
1003:          m11 += mat.m11;
1004:          m12 += mat.m12;
1005:          m20 += mat.m20;
1006:          m21 += mat.m21;
1007:          m22 += mat.m22;
1008:      }
1009:   
1010:      /**
1011:       * transpose locally transposes this Matrix. This is
1012:       * inconsistent with general value vs local semantics, but is preserved for
1013:       * backwards compatibility. Use transposeNew() to transpose to a new object
1014:       * (value).
1015:       * 转置矩阵
1016:       * 
1017:       * @return this object for chaining.
1018:       */
1019:      public Matrix3f transpose() {
1020:          return transposeLocal();
1021:      }
1022:   
1023:      /**
1024:       * transposeNew returns a transposed version of this matrix.
1025:       * 转置矩阵
1026:       * 
1027:       * @return The new Matrix3f object.
1028:       */
1029:      public Matrix3f transposeNew() {
1030:          Matrix3f ret = new Matrix3f(m00, m10, m20, m01, m11, m21, m02, m12, m22);
1031:          return ret;
1032:      }
1033:   
1034:      /**
1035:       * toString returns the string representation of this object.
1036:       * It is in a format of a 3x3 matrix. For example, an identity matrix would
1037:       * be represented by the following string. com.jme.math.Matrix3f 
1038:       * [
1039:       * 1.0 0.0 0.0 
1040:       * 0.0 1.0 0.0 
1041:       * 0.0 0.0 1.0 
1042:       * ]
1043:       * 
1044:       * @return the string representation of this object.
1045:       */
1046:      public String toString() {
1047:          StringBuffer result = new StringBuffer("com.jme.math.Matrix3f/n[/n");
1048:          result.append(" ");
1049:          result.append(m00);
1050:          result.append("  ");
1051:          result.append(m01);
1052:          result.append("  ");
1053:          result.append(m02);
1054:          result.append(" /n");
1055:          result.append(" ");
1056:          result.append(m10);
1057:          result.append("  ");
1058:          result.append(m11);
1059:          result.append("  ");
1060:          result.append(m12);
1061:          result.append(" /n");
1062:          result.append(" ");
1063:          result.append(m20);
1064:          result.append("  ");
1065:          result.append(m21);
1066:          result.append("  ");
1067:          result.append(m22);
1068:          result.append(" /n]");
1069:          return result.toString();
1070:      }
1071:   
1072:      /**
1073:       * 
1074:       * hashCode returns the hash code value as an integer and is
1075:       * supported for the benefit of hashing based collection classes such as
1076:       * Hashtable, HashMap, HashSet etc.
1077:       * 
1078:       * @return the hashcode for this instance of Matrix4f.
1079:       * @see java.lang.Object#hashCode()
1080:       */
1081:      public int hashCode() {
1082:          int hash = 37;
1083:          hash = 37 * hash + Float.floatToIntBits(m00);
1084:          hash = 37 * hash + Float.floatToIntBits(m01);
1085:          hash = 37 * hash + Float.floatToIntBits(m02);
1086:   
1087:          hash = 37 * hash + Float.floatToIntBits(m10);
1088:          hash = 37 * hash + Float.floatToIntBits(m11);
1089:          hash = 37 * hash + Float.floatToIntBits(m12);
1090:   
1091:          hash = 37 * hash + Float.floatToIntBits(m20);
1092:          hash = 37 * hash + Float.floatToIntBits(m21);
1093:          hash = 37 * hash + Float.floatToIntBits(m22);
1094:   
1095:          return hash;
1096:      }
1097:   
1098:      /**
1099:       * are these two matrices the same? they are is they both have the same mXX
1100:       * values.
1101:       * 
1102:       * @param o
1103:       *            the object to compare for equality
1104:       * @return true if they are equal
1105:       */
1106:      public boolean equals(Object o) {
1107:          if (!(o instanceof Matrix3f) || o == null) {
1108:              return false;
1109:          }
1110:   
1111:          if (this == o) {
1112:              return true;
1113:          }
1114:   
1115:          Matrix3f comp = (Matrix3f) o;
1116:          if (Float.compare(m00, comp.m00) != 0)
1117:              return false;
1118:          if (Float.compare(m01, comp.m01) != 0)
1119:              return false;
1120:          if (Float.compare(m02, comp.m02) != 0)
1121:              return false;
1122:   
1123:          if (Float.compare(m10, comp.m10) != 0)
1124:              return false;
1125:          if (Float.compare(m11, comp.m11) != 0)
1126:              return false;
1127:          if (Float.compare(m12, comp.m12) != 0)
1128:              return false;
1129:   
1130:          if (Float.compare(m20, comp.m20) != 0)
1131:              return false;
1132:          if (Float.compare(m21, comp.m21) != 0)
1133:              return false;
1134:          if (Float.compare(m22, comp.m22) != 0)
1135:              return false;
1136:   
1137:          return true;
1138:      }
1139:   
1140:      public void write(JMEExporter e) throws IOException {
1141:          OutputCapsule cap = e.getCapsule(this);
1142:          cap.write(m00, "m00", 1);
1143:          cap.write(m01, "m01", 0);
1144:          cap.write(m02, "m02", 0);
1145:          cap.write(m10, "m10", 0);
1146:          cap.write(m11, "m11", 1);
1147:          cap.write(m12, "m12", 0);
1148:          cap.write(m20, "m20", 0);
1149:          cap.write(m21, "m21", 0);
1150:          cap.write(m22, "m22", 1);
1151:      }
1152:   
1153:      public void read(JMEImporter e) throws IOException {
1154:          InputCapsule cap = e.getCapsule(this);
1155:          m00 = cap.readFloat("m00", 1);
1156:          m01 = cap.readFloat("m01", 0);
1157:          m02 = cap.readFloat("m02", 0);
1158:          m10 = cap.readFloat("m10", 0);
1159:          m11 = cap.readFloat("m11", 1);
1160:          m12 = cap.readFloat("m12", 0);
1161:          m20 = cap.readFloat("m20", 0);
1162:          m21 = cap.readFloat("m21", 0);
1163:          m22 = cap.readFloat("m22", 1);
1164:      }
1165:   
1166:      public Class
  
  extends Matrix3f> getClassTag() {
1167:          return this.getClass();
1168:      }
1169:   
1170:      /**
1171:       * A function for creating a rotation matrix that rotates a vector called
1172:       * "start" into another vector called "end".
1173:       * 创建一个旋转矩阵,从向量start旋转到end
1174:       * 
1175:       * @param start
1176:       *            normalized non-zero starting vector
1177:       * @param end
1178:       *            normalized non-zero ending vector
1179:       * @see "Tomas M?ller, John Hughes /"Efficiently Building a Matrix to Rotate
1180:       *      / One Vector to Another/" Journal of Graphics Tools, 4(4):1-4, 1999"
1181:       */
1182:      public void fromStartEndVectors(Vector3f start, Vector3f end) {
1183:          Vector3f v = new Vector3f();
1184:          float e, h, f;
1185:   
1186:          start.cross(end, v);
1187:          e = start.dot(end);
1188:          f = (e < 0) ? -e : e;
1189:   
1190:          // if "from" and "to" vectors are nearly parallel
1191:          if (f > 1.0f - FastMath.ZERO_TOLERANCE) {
1192:              Vector3f u = new Vector3f();
1193:              Vector3f x = new Vector3f();
1194:              float c1, c2, c3; /* coefficients for later use */
1195:              int i, j;
1196:   
1197:              x.x = (start.x > 0.0) ? start.x : -start.x;
1198:              x.y = (start.y > 0.0) ? start.y : -start.y;
1199:              x.z = (start.z > 0.0) ? start.z : -start.z;
1200:   
1201:              if (x.x < x.y) {
1202:                  if (x.x < x.z) {
1203:                      x.x = 1.0f;
1204:                      x.y = x.z = 0.0f;
1205:                  } else {
1206:                      x.z = 1.0f;
1207:                      x.x = x.y = 0.0f;
1208:                  }
1209:              } else {
1210:                  if (x.y < x.z) {
1211:                      x.y = 1.0f;
1212:                      x.x = x.z = 0.0f;
1213:                  } else {
1214:                      x.z = 1.0f;
1215:                      x.x = x.y = 0.0f;
1216:                  }
1217:              }
1218:   
1219:              u.x = x.x - start.x;
1220:              u.y = x.y - start.y;
1221:              u.z = x.z - start.z;
1222:              v.x = x.x - end.x;
1223:              v.y = x.y - end.y;
1224:              v.z = x.z - end.z;
1225:   
1226:              c1 = 2.0f / u.dot(u);
1227:              c2 = 2.0f / v.dot(v);
1228:              c3 = c1 * c2 * u.dot(v);
1229:   
1230:              for (i = 0; i < 3; i++) {
1231:                  for (j = 0; j < 3; j++) {
1232:                      float val = -c1 * u.get(i) * u.get(j) - c2 * v.get(i)
1233:                              * v.get(j) + c3 * v.get(i) * u.get(j);
1234:                      set(i, j, val);
1235:                  }
1236:                  float val = get(i, i);
1237:                  set(i, i, val + 1.0f);
1238:              }
1239:          } else {
1240:              // the most common case, unless "start"="end", or "start"=-"end"
1241:              float hvx, hvz, hvxy, hvxz, hvyz;
1242:              h = 1.0f / (1.0f + e);
1243:              hvx = h * v.x;
1244:              hvz = h * v.z;
1245:              hvxy = hvx * v.y;
1246:              hvxz = hvx * v.z;
1247:              hvyz = hvz * v.y;
1248:              set(0, 0, e + hvx * v.x);
1249:              set(0, 1, hvxy - v.z);
1250:              set(0, 2, hvxz + v.y);
1251:   
1252:              set(1, 0, hvxy + v.z);
1253:              set(1, 1, e + h * v.y * v.y);
1254:              set(1, 2, hvyz - v.x);
1255:   
1256:              set(2, 0, hvxz - v.y);
1257:              set(2, 1, hvyz + v.x);
1258:              set(2, 2, e + hvz * v.z);
1259:          }
1260:      }
1261:   
1262:      /**
1263:       * scale scales the operation performed by this matrix on a
1264:       * per-component basis.
1265:       * 标量乘行向量,各列分别相乘
1266:       * 
1267:       * @param scale
1268:       *            The scale applied to each of the X, Y and Z output values.
1269:       */
1270:      public void scale(Vector3f scale) {
1271:          m00 *= scale.x;
1272:          m10 *= scale.x;
1273:          m20 *= scale.x;
1274:          m01 *= scale.y;
1275:          m11 *= scale.y;
1276:          m21 *= scale.y;
1277:          m02 *= scale.z;
1278:          m12 *= scale.z;
1279:          m22 *= scale.z;
1280:      }
1281:   
1282:      static final boolean equalIdentity(Matrix3f mat) {
1283:          if (Math.abs(mat.m00 - 1) > 1e-4)
1284:              return false;
1285:          if (Math.abs(mat.m11 - 1) > 1e-4)
1286:              return false;
1287:          if (Math.abs(mat.m22 - 1) > 1e-4)
1288:              return false;
1289:   
1290:          if (Math.abs(mat.m01) > 1e-4)
1291:              return false;
1292:          if (Math.abs(mat.m02) > 1e-4)
1293:              return false;
1294:   
1295:          if (Math.abs(mat.m10) > 1e-4)
1296:              return false;
1297:          if (Math.abs(mat.m12) > 1e-4)
1298:              return false;
1299:   
1300:          if (Math.abs(mat.m20) > 1e-4)
1301:              return false;
1302:          if (Math.abs(mat.m21) > 1e-4)
1303:              return false;
1304:   
1305:          return true;
1306:      }
1307:   
1308:      @Override
1309:      public Matrix3f clone() {
1310:          try {
1311:              return (Matrix3f) super.clone();
1312:          } catch (CloneNotSupportedException e) {
1313:              throw new AssertionError(); // can not happen
1314:          }
1315:      }
1316:  }

 

绕任意轴(n是单位向量)旋转的3D旋转矩阵:

clip_image053[9]

 1:  /**
 2:   * fromAngleNormalAxis sets this matrix4f to the values
 3:   * specified by an angle and a normalized axis of rotation.
 4:   * 绕轴axis(单位向量)旋转angle(弧度)角的3D旋转矩阵
 5:   * 
 6:   * @param angle
 7:   *            the angle to rotate (in radians).
 8:   * @param axis
 9:   *            the axis of rotation (already normalized).
10:   */
11:  public void fromAngleNormalAxis(float angle, Vector3f axis) {
12:      float fCos = FastMath.cos(angle);
13:      float fSin = FastMath.sin(angle);
14:      float fOneMinusCos = ((float) 1.0) - fCos;
15:      float fX2 = axis.x * axis.x;
16:      float fY2 = axis.y * axis.y;
17:      float fZ2 = axis.z * axis.z;
18:      float fXYM = axis.x * axis.y * fOneMinusCos;
19:      float fXZM = axis.x * axis.z * fOneMinusCos;
20:      float fYZM = axis.y * axis.z * fOneMinusCos;
21:      float fXSin = axis.x * fSin;
22:      float fYSin = axis.y * fSin;
23:      float fZSin = axis.z * fSin;
24:   
25:      m00 = fX2 * fOneMinusCos + fCos;
26:      m01 = fXYM - fZSin;
27:      m02 = fXZM + fYSin;
28:      m10 = fXYM + fZSin;
29:      m11 = fY2 * fOneMinusCos + fCos;
30:      m12 = fYZM - fXSin;
31:      m20 = fXZM - fYSin;
32:      m21 = fYZM + fXSin;
33:      m22 = fZ2 * fOneMinusCos + fCos;
34:  }

矩阵乘法:

clip_image021[9]

 1:  public Matrix3f mult(Matrix3f mat, Matrix3f product) {
 2:   
 3:      float temp00, temp01, temp02;
 4:      float temp10, temp11, temp12;
 5:      float temp20, temp21, temp22;
 6:   
 7:      if (product == null)
 8:          product = new Matrix3f();
 9:      temp00 = m00 * mat.m00 + m01 * mat.m10 + m02 * mat.m20;
10:      temp01 = m00 * mat.m01 + m01 * mat.m11 + m02 * mat.m21;
11:      temp02 = m00 * mat.m02 + m01 * mat.m12 + m02 * mat.m22;
12:      temp10 = m10 * mat.m00 + m11 * mat.m10 + m12 * mat.m20;
13:      temp11 = m10 * mat.m01 + m11 * mat.m11 + m12 * mat.m21;
14:      temp12 = m10 * mat.m02 + m11 * mat.m12 + m12 * mat.m22;
15:      temp20 = m20 * mat.m00 + m21 * mat.m10 + m22 * mat.m20;
16:      temp21 = m20 * mat.m01 + m21 * mat.m11 + m22 * mat.m21;
17:      temp22 = m20 * mat.m02 + m21 * mat.m12 + m22 * mat.m22;
18:   
19:      product.m00 = temp00;
20:      product.m01 = temp01;
21:      product.m02 = temp02;
22:      product.m10 = temp10;
23:      product.m11 = temp11;
24:      product.m12 = temp12;
25:      product.m20 = temp20;
26:      product.m21 = temp21;
27:      product.m22 = temp22;
28:   
29:      return product;
30:  }

向量与矩阵相乘:

 clip_image024[9]

 1:  public Vector3f mult(Vector3f vec, Vector3f product) {
 2:   
 3:      if (null == product) {
 4:          product = new Vector3f();
 5:      }
 6:   
 7:      float x = vec.x;
 8:      float y = vec.y;
 9:      float z = vec.z;
10:   
11:      product.x = m00 * x + m01 * y + m02 * z;
12:      product.y = m10 * x + m11 * y + m12 * z;
13:      product.z = m20 * x + m21 * y + m22 * z;
14:      return product;
15:  }

逆矩阵:

标准伴随矩阵:adj M,定义为M的代数余子式矩阵的转置矩阵。

矩阵的逆能用标准伴随矩阵除以行列式来求得:

clip_image030[9]

 1:  public Matrix3f invert(Matrix3f store) {
 2:      if (store == null)
 3:          store = new Matrix3f();
 4:   
 5:      float det = determinant();
 6:      if (FastMath.abs(det) <= 0)
 7:          return store.zero();
 8:   
 9:      store.m00 = m11 * m22 - m12 * m21;
10:      store.m01 = m02 * m21 - m01 * m22;
11:      store.m02 = m01 * m12 - m02 * m11;
12:      store.m10 = m12 * m20 - m10 * m22;
13:      store.m11 = m00 * m22 - m02 * m20;
14:      store.m12 = m02 * m10 - m00 * m12;
15:      store.m20 = m10 * m21 - m11 * m20;
16:      store.m21 = m01 * m20 - m00 * m21;
17:      store.m22 = m00 * m11 - m01 * m10;
18:   
19:      store.multLocal(1f / det);
20:      return store;
21:  }

方阵M的行列式:

clip_image025[9]

clip_image026[9]

clip_image027[9]

1:  public float determinant() {
2:      float fCo00 = m11 * m22 - m12 * m21;
3:      float fCo10 = m12 * m20 - m10 * m22;
4:      float fCo20 = m10 * m21 - m11 * m20;
5:      float fDet = m00 * fCo00 + m01 * fCo10 + m02 * fCo20;
6:      return fDet;
7:  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值