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 newMatrix3f
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 newMatrix3f
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 aJmeException
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 aVector3f
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 aVector3f
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 aVector3f
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 aVector3f
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 aJmeException
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 givenVector3f
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旋转矩阵:
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: }
矩阵乘法:
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: }
向量与矩阵相乘:
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的代数余子式矩阵的转置矩阵。
矩阵的逆能用标准伴随矩阵除以行列式来求得:
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的行列式:
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: }