/* * pMatrix.java v0.01 May 16th, 1998 * * A general purpose (rotation and translation) matrix. * (05/16/1998,05/17/1998,4/2005) * * Copyright(c) 1998, Alex S, Particle */ import java.lang.String; import java.util.Vector; /** * pMatrix class, to handle all the matrix thingies. * the class represents a 4x4 matrix, with some * useful operations defined on it. * * Note: This thing is Right Handed!; just like OpenGL :-) */ public class pMatrix { /** * the matrix stored as 2D array. */ protected float[] matrix; /** * the stack to hold working matrices. */ protected static Vector stack; /** * get the stack going... */ static{ stack = new Vector(); } /** * default constructor, initializes the matrix, * and makes sure it's an "intentity" matrix. */ public pMatrix(){ matrix = new float[16]; ident(); } /** * create a matrix from a 16 element array */ public pMatrix(float[] m){ matrix = new float[16]; System.arraycopy(m,0,matrix, 0, 16); } /** * a copy constructor. * * @param m The matrix to copy. */ public pMatrix(pMatrix m){ matrix = new float[16]; System.arraycopy(m.matrix, 0, matrix, 0, 16); } /** * pushes the current matrix onto the stack, * (the current matrix is still there though) */ public void push(){ pMatrix tmp = new pMatrix(this); stack.addElement(tmp.matrix); } /** * pops the last pushed matrix from the stack, * and makes it current. (the previous one is * erased) *

* NOTE: no error checking is performed, you WILL * get a NoSuchElementException if you're not careful * and try to pop an empty stack. * * @return The freshly poped matrix. */ public pMatrix pop(){ matrix = (float[])stack.lastElement(); stack.removeElement(matrix); return this; } /** * makes this matrix into an identity matrix. * (current info of the matrix is erased) * * @return Current identity matrix. */ public pMatrix ident(){ for (int i=0;i<4;i++) for (int j=0;j<4;j++) matrix[(i<<2)+j] = i == j ? 1:0; return this; } /** * add another matrix to this one. * (changes current matrix) * * @param m The matrix to add. * @return The current changed matrix. */ public pMatrix add(pMatrix m){ for (int i=0;i<16;i++) matrix[i] += m.matrix[i]; return this; } /** * subtract a matrix from this one * (changes the current matrix) * * @param m The matrix to subtract. * @return The current changed matrix. */ public pMatrix sub(pMatrix m){ for (int i=0;i<16;i++) matrix[i] -= m.matrix[i]; return this; } /** * get function to the rest of the world. * * @param i The column. * @param j The row. * @return The location of that row and column. */ public float get(int i,int j){ return matrix[(i<<2)+j]; } /** * set function for the rest of the world. * * @param i The column. * @param j The row. * @param v The value of the new location. */ public void set(int i,int j,float v){ matrix[(i<<2)+j] = v; } /** * function to multiply this matrix by another. * (the result is a cross multiply of this matrix * by the parameter matrix.) * (current matrix changes!) * * @param m The matrix to multiply by. * @return The current changed matrix. */ public pMatrix mult(pMatrix m){ pMatrix tmp = new pMatrix(this); for (int i=0;i<4;i++) for (int j=0;j<4;j++) { matrix[(i<<2)+j] = 0; for (int k=0;k<4;k++) matrix[(i<<2)+j] += tmp.matrix[(i<<2)+k] * m.matrix[(k<<2)+j]; } return this; } /** * function to transform a vector, * (a vector consists of a 4 element array of floats, * the last element of the array is reserved) * * @param v The vector to transform. * @return The transformed vector. */ public float[] mult(float[] v){ float[] tmp = new float[4]; int i; for (i=0;i<4;i++) tmp[i] = v[i]; for (i=0;i<4;i++) { v[i] = 0; for (int j=0;j<4;j++) v[i] += matrix[(i<<2)+j] * tmp[j]; } return v; } /** * function to transform an array of vectors... * * @param a The array of arrays of vectors. * @return The transformed array... */ public float[][] mult(float[][] a){ for (int i=0;i= i ) ? 1 : 0 ); sj = dj + ( ( dj >= j ) ? 1 : 0 ); // copy element mb[di * 3 + dj] = mr[si * 4 + sj]; } } } private static float m4_det(float[] mr) { float det, result = 0, i = 1; float[] msub3 = new float[3*3]; int n; for ( n = 0; n < 4; n++, i *= -1 ){ m4_submat( mr, msub3, 0, n ); det = m3_det( msub3 ); result += mr[n] * det * i; } return result; } private static boolean m4_inverse(float[] mr, float[] ma ){ float mdet = m4_det( ma ); float[] mtemp = new float[3*3]; int i, j, sign; if (Math.abs( mdet ) < (float)0.0005 ){ // m4_identity( mr ); return false; } for ( i = 0; i < 4; i++ ) for ( j = 0; j < 4; j++ ){ sign = 1 - ( (i +j) % 2 ) * 2; m4_submat( ma, mtemp, i, j ); mr[i+j*4] = ( m3_det( mtemp ) * sign ) / mdet; } return true; } }