[PULL] Surface transformations v1

Bill Spitzak spitzak at gmail.com
Fri Jan 27 13:27:02 PST 2012


I have no idea if you need this, but here is free code to do the matrix 
inversion. This is code I wrote and is public domain (although I 
certainly referred to a book to generate it, but I can't see that being 
a copyright problem).

The matrix struct uses aRC as the variable name for the entry in row R 
and column C. It is pretty much this:

struct Matrix {
   // Note transposition to OpenGL order!
   float a00, a10, a20, a30,
	a01, a11, a21, a31,
	a02, a12, a22, a32,
	a03, a13, a23, a33;
};

These are C++ methods on the matrix object, but you can change it to C 
by adding a "this" argument and adding it to all the axy references:

   float determinant(void) const {
   return
      a01*a23*a32*a10 -a01*a22*a33*a10 -a23*a31*a02*a10 +a22*a31*a03*a10
     -a00*a23*a32*a11 +a00*a22*a33*a11 +a23*a30*a02*a11 -a22*a30*a03*a11
     -a01*a23*a30*a12 +a00*a23*a31*a12 +a01*a22*a30*a13 -a00*a22*a31*a13
     -a33*a02*a11*a20 +a32*a03*a11*a20 +a01*a33*a12*a20 -a31*a03*a12*a20
     -a01*a32*a13*a20 +a31*a02*a13*a20 +a33*a02*a10*a21 -a32*a03*a10*a21
     -a00*a33*a12*a21 +a30*a03*a12*a21 +a00*a32*a13*a21 -a30*a02*a13*a21;
   }

// Usually code needs to figure out the determinant anyway, so this
// takes it as an argument. o must not be the same as this.
void invert(float det, Matrix& o) const {
   float d = 1.0f/det;
   o.a00 = (-a23*a32*a11 +a22*a33*a11 +a23*a31*a12 -a22*a31*a13 
-a33*a12*a21 +a32*a13*a21) * d;
   o.a01 = ( a01*a23*a32 -a01*a22*a33 -a23*a31*a02 +a22*a31*a03 
+a33*a02*a21 -a32*a03*a21) * d;
   o.a02 = (-a33*a02*a11 +a32*a03*a11 +a01*a33*a12 -a31*a03*a12 
-a01*a32*a13 +a31*a02*a13) * d;
   m.a03 = ( a23*a02*a11 -a22*a03*a11 -a01*a23*a12 +a01*a22*a13 
+a03*a12*a21 -a02*a13*a21) * d;

   o.a10 = ( a23*a32*a10 -a22*a33*a10 -a23*a30*a12 +a22*a30*a13 
+a33*a12*a20 -a32*a13*a20) * d;
   o.a11 = (-a00*a23*a32 +a00*a22*a33 +a23*a30*a02 -a22*a30*a03 
-a33*a02*a20 +a32*a03*a20) * d;
   o.a12 = ( a33*a02*a10 -a32*a03*a10 -a00*a33*a12 +a30*a03*a12 
+a00*a32*a13 -a30*a02*a13) * d;
   o.a13 = (-a23*a02*a10 +a22*a03*a10 +a00*a23*a12 -a00*a22*a13 
-a03*a12*a20 +a02*a13*a20) * d;

   o.a20 = (-a23*a31*a10 +a23*a30*a11 -a33*a11*a20 +a31*a13*a20 
+a33*a10*a21 -a30*a13*a21) * d;
   o.a21 = (-a01*a23*a30 +a00*a23*a31 +a01*a33*a20 -a31*a03*a20 
-a00*a33*a21 +a30*a03*a21) * d;
   o.a22 = (-a01*a33*a10 +a31*a03*a10 +a00*a33*a11 -a30*a03*a11 
+a01*a30*a13 -a00*a31*a13) * d;
   o.a23 = ( a01*a23*a10 -a00*a23*a11 +a03*a11*a20 -a01*a13*a20 
-a03*a10*a21 +a00*a13*a21) * d;

   o.a30 = ( a22*a31*a10 -a22*a30*a11 +a32*a11*a20 -a31*a12*a20 
-a32*a10*a21 +a30*a12*a21) * d;
   o.a31 = ( a01*a22*a30 -a00*a22*a31 -a01*a32*a20 +a31*a02*a20 
+a00*a32*a21 -a30*a02*a21) * d;
   o.a32 = ( a01*a32*a10 -a31*a02*a10 -a00*a32*a11 +a30*a02*a11 
-a01*a30*a12 +a00*a31*a12) * d;
   o.a33 = (-a01*a22*a10 +a00*a22*a11 -a02*a11*a20 +a01*a12*a20 
+a02*a10*a21 -a00*a12*a21) * d;
}

Pekka Paalanen wrote:

> This series also includes X/MIT-like licenced code for inverting a 4x4
> matrix by LU-decomposition. I could not find one in the web, so I
> implemented it from a book (*not* Numerical Recipes in C or C++, since
> they impose licence issues). The reference is in the source. Anyone
> working on their hobby graphics engine might be interested ;-)
> For testing the matrix inversion alone, there is a standalone unit test
> application.


More information about the wayland-devel mailing list