Lucretia

04-17-2004, 04:41 PM

Hi,

I've just started getting back into OpenGL and have started to write some matrix functions. I decided to separate out the 4x4 matrix into a 3x3 matrix for rotation and scale and use a 3 vector for the translation. Now, I worked out the proof that I needed to compose this into a 4x4 matrix.

Given that a 4x4 matrix is composed thus:

|M|T|

M1 = -----

|0|1|Where M1 is a 3x3 matrix and T is a column vector representing the translation.

This is the formula for multiplying 2 4x4 matrices:

|m0 m4 m8 m12| |t0 t4 t8 t12|

M = |m1 m5 m9 m13| T = |t1 t5 t9 t13|

|m2 m6 m10 m14| |t2 t6 t10 t14|

|m3 m7 m11 m15| |t3 t7 t11 t15|

|(m0t0 + m4t1 + m8t2 + m12t3) (m0t4 + m4t5 + m8t6 + m12t7) (m0t8 + m4t9 + m8t10 + m12t11) (m0t12 + m4t13 + m8t14 + m12t15)|

MT = |(m1t0 + m5t1 + m9t2 + m13t3) (m1t4 + m5t5 + m9t6 + m13t7) (m1t8 + m5t9 + m9t10 + m13t11) (m1t12 + m5t13 + m9t14 + m13t15)|

|(m2t0 + m6t1 + m10t2 + m14t3) (m2t4 + m6t5 + m10t6 + m14t7) (m2t8 + m6t9 + m10t10 + m14t11) (m2t12 + m6t13 + m10t14 + m14t15)|

|(m3t0 + m7t1 + m11t2 + m15t3) (m3t4 + m7t5 + m11t6 + m15t7) (m3t8 + m7t9 + m11t10 + m15t11) (m3t12 + m7t13 + m11t14 + m15t15)|So, substituting:

Proof 1:

|m0 m4 m8 0| |1 0 0 t0|

|m1 m5 m9 0| * |0 1 0 t1| =

|m2 m6 m10 0| |0 0 1 t2|

|0 0 0 1| |0 0 0 1 |

|(m0(1) + m4(0) + m8(0) + (0)(0)) (m0(0) + m4(1) + m8(0) + (0)(0)) (m0(0) + m4(0) + m8(1) + (0)(0)) (m0t0 + m4t1 + m8t2 + (0)(0))|

|(m1(1) + m5(0) + m9(0) + (0)(0)) (m1(0) + m5(1) + m9(0) + (0)(0)) (m1(0) + m5(0) + m9(1) + (0)(0)) (m1t0 + m5t1 + m9t2 + (0)(0))| =

|(m2(1) + m6(0) + m10(0) + (0)(0)) (m2(0) + m6(1) + m10(0) + (0)(0)) (m2(0) + m6(0) + m10(1) + (0)(0)) (m2t0 + m6t1 + m10t2 + (0)(0))|

|((0)(1) + (0)(0) + (0)(0) + (1)(0)) ((0)(0) + (0)(1) + (0)(0) + (1)(0)) ((0)(0) + (0)(0) + (0)(1) + (1)(0)) ((0)t0 + (0)t1 + (0)t2 + (1)(1))|

|(m0) (m4) (m8 ) (m0t0 + m4t1 + m8t2 )|

|(m1) (m5) (m9 ) (m1t0 + m5t1 + m9t2 )|

|(m2) (m6) (m10) (m2t0 + m6t1 + m10t2)|

|(0 ) (0 ) (0 ) (1 )|And, now if I multiply a 3x3 matrix with a 3 vector:

Proof 2:

|m0 m4 m8 | |t0|

|m1 m5 m9 | * |t1| =

|m2 m6 m10| |t2|

|m0t0 + m4t1 + m8t2 |

|m1t0 + m5t1 + m9t2 |

|m2t0 + m6t1 + m10t2|So, proof 2 is the same as the translation part of the matrix in proof 1, hence to compose a 4x4 matrix from a 3x3 and a vector, the final formula is:

|M|MT|

M2 = ------

|0|1 |Now, from my code, this doesn't quite work out. Yet, if I don't multiply the translation by the 3x3 matrix when I compose the 4x4, everything is fine, yet I don't quite understand why this works?

I have seen a post on here that noted that M1 is equal to a rotation followed by a translation, and M2 is the opposite. But, surely if this were correct, M2 would work as expected, yet it doesn't; it's almost as though the triangle I'm rotating is being sheared.

Can somebody shed some light on this problem?

Thanks,

Luke.

I've just started getting back into OpenGL and have started to write some matrix functions. I decided to separate out the 4x4 matrix into a 3x3 matrix for rotation and scale and use a 3 vector for the translation. Now, I worked out the proof that I needed to compose this into a 4x4 matrix.

Given that a 4x4 matrix is composed thus:

|M|T|

M1 = -----

|0|1|Where M1 is a 3x3 matrix and T is a column vector representing the translation.

This is the formula for multiplying 2 4x4 matrices:

|m0 m4 m8 m12| |t0 t4 t8 t12|

M = |m1 m5 m9 m13| T = |t1 t5 t9 t13|

|m2 m6 m10 m14| |t2 t6 t10 t14|

|m3 m7 m11 m15| |t3 t7 t11 t15|

|(m0t0 + m4t1 + m8t2 + m12t3) (m0t4 + m4t5 + m8t6 + m12t7) (m0t8 + m4t9 + m8t10 + m12t11) (m0t12 + m4t13 + m8t14 + m12t15)|

MT = |(m1t0 + m5t1 + m9t2 + m13t3) (m1t4 + m5t5 + m9t6 + m13t7) (m1t8 + m5t9 + m9t10 + m13t11) (m1t12 + m5t13 + m9t14 + m13t15)|

|(m2t0 + m6t1 + m10t2 + m14t3) (m2t4 + m6t5 + m10t6 + m14t7) (m2t8 + m6t9 + m10t10 + m14t11) (m2t12 + m6t13 + m10t14 + m14t15)|

|(m3t0 + m7t1 + m11t2 + m15t3) (m3t4 + m7t5 + m11t6 + m15t7) (m3t8 + m7t9 + m11t10 + m15t11) (m3t12 + m7t13 + m11t14 + m15t15)|So, substituting:

Proof 1:

|m0 m4 m8 0| |1 0 0 t0|

|m1 m5 m9 0| * |0 1 0 t1| =

|m2 m6 m10 0| |0 0 1 t2|

|0 0 0 1| |0 0 0 1 |

|(m0(1) + m4(0) + m8(0) + (0)(0)) (m0(0) + m4(1) + m8(0) + (0)(0)) (m0(0) + m4(0) + m8(1) + (0)(0)) (m0t0 + m4t1 + m8t2 + (0)(0))|

|(m1(1) + m5(0) + m9(0) + (0)(0)) (m1(0) + m5(1) + m9(0) + (0)(0)) (m1(0) + m5(0) + m9(1) + (0)(0)) (m1t0 + m5t1 + m9t2 + (0)(0))| =

|(m2(1) + m6(0) + m10(0) + (0)(0)) (m2(0) + m6(1) + m10(0) + (0)(0)) (m2(0) + m6(0) + m10(1) + (0)(0)) (m2t0 + m6t1 + m10t2 + (0)(0))|

|((0)(1) + (0)(0) + (0)(0) + (1)(0)) ((0)(0) + (0)(1) + (0)(0) + (1)(0)) ((0)(0) + (0)(0) + (0)(1) + (1)(0)) ((0)t0 + (0)t1 + (0)t2 + (1)(1))|

|(m0) (m4) (m8 ) (m0t0 + m4t1 + m8t2 )|

|(m1) (m5) (m9 ) (m1t0 + m5t1 + m9t2 )|

|(m2) (m6) (m10) (m2t0 + m6t1 + m10t2)|

|(0 ) (0 ) (0 ) (1 )|And, now if I multiply a 3x3 matrix with a 3 vector:

Proof 2:

|m0 m4 m8 | |t0|

|m1 m5 m9 | * |t1| =

|m2 m6 m10| |t2|

|m0t0 + m4t1 + m8t2 |

|m1t0 + m5t1 + m9t2 |

|m2t0 + m6t1 + m10t2|So, proof 2 is the same as the translation part of the matrix in proof 1, hence to compose a 4x4 matrix from a 3x3 and a vector, the final formula is:

|M|MT|

M2 = ------

|0|1 |Now, from my code, this doesn't quite work out. Yet, if I don't multiply the translation by the 3x3 matrix when I compose the 4x4, everything is fine, yet I don't quite understand why this works?

I have seen a post on here that noted that M1 is equal to a rotation followed by a translation, and M2 is the opposite. But, surely if this were correct, M2 would work as expected, yet it doesn't; it's almost as though the triangle I'm rotating is being sheared.

Can somebody shed some light on this problem?

Thanks,

Luke.