Matrix4f: determinant function

Started by mstWeal, September 08, 2010, 21:04:08

Previous topic - Next topic

mstWeal

Hey guys,

I don't know if it's just me but the function determinant() of the Matrix4f utility class seems to produce somewhat strange results (and as a result of that also the invert() function).

I used the following test code:

Matrix4f test = new Matrix4f();
FloatBuffer buf = BufferUtils.createFloatBuffer(16);
buf.put(1);
buf.put(2);
buf.put(3);
buf.put(4);
buf.put(5);
buf.put(6);
buf.put(7);
buf.put(8);
buf.put(9);
buf.put(10);
buf.put(11);
buf.put(12);
buf.put(13);
buf.put(14);
buf.put(15);
buf.put(16);
buf.rewind();
test.load(buf);
System.out.println(test.determinant());


This prints out 0 for me. I debugged into the determinant function where I found the following code:

float f =
			m00
				* ((m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32)
					- m13 * m22 * m31
					- m11 * m23 * m32
					- m12 * m21 * m33);
		f -= m01
			* ((m10 * m22 * m33 + m12 * m23 * m30 + m13 * m20 * m32)
				- m13 * m22 * m30
				- m10 * m23 * m32
				- m12 * m20 * m33);
		f += m02
			* ((m10 * m21 * m33 + m11 * m23 * m30 + m13 * m20 * m31)
				- m13 * m21 * m30
				- m10 * m23 * m31
				- m11 * m20 * m33);
		f -= m03
			* ((m10 * m21 * m32 + m11 * m22 * m30 + m12 * m20 * m31)
				- m12 * m21 * m30
				- m10 * m22 * m31
				- m11 * m20 * m32);
		return f;


I use the debugger to display the values at each step. I noticed that for the first statement:

float f =
			m00
				* ((m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32)
					- m13 * m22 * m31
					- m11 * m23 * m32
					- m12 * m21 * m33);


If you take the values on the right hand side but without the last m33 all works fine:

(m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32)
					- m13 * m22 * m31
					- m11 * m23 * m32
					- m12 * m21


->  = 1050.0

And as soon as I try to display the value with the m33 it suddenly becomes 0.0 but obviously, 1050.0 * 16.0 is not 0.0 ...

There seems to be a problem with the float datatype processing such a long statement. As I based my Matrix class on the LWJGL class and I was able to quickly change that code. I split it up into several statements:

public float determinant() {
		float determinant = 0;

		float val1 = (m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32);
		float val2 = m13 * m22 * m31 - m11 * m23 * m32 - m12 * m21 * m33;
		determinant = m00 * (val1 - val2);

		val1 = (m10 * m22 * m33 + m12 * m23 * m30 + m13 * m20 * m32);
		val2 = m13 * m22 * m30 - m10 * m23 * m32 - m12 * m20 * m33;
		determinant -= m01 * (val1 - val2);

		val1 = (m10 * m21 * m33 + m11 * m23 * m30 + m13 * m20 * m31);
		val2 = m13 * m21 * m30 - m10 * m23 * m31 - m11 * m20 * m33;
		determinant += m02 * (val1 - val2);

		val1 = (m10 * m21 * m32 + m11 * m22 * m30 + m12 * m20 * m31);
		val2 = m12 * m21 * m30 - m10 * m22 * m31 - m11 * m20 * m32;
		determinant -= m03 * (val1 - val2);

		return determinant;
	}


and it works fine now.

mstWeal

Come on guys what's up? You all using your own Matrix classes or what? ^ ^