confused about matrix and transform
Hello there.
I'm reading some articles about matrix these days.
someone says that the matrix transform looks like this:
[ m, m, m, m,
[x, y, z, w] X m, m, m, m, = [x', y', z', w']
m, m, m, m,
m, m, m, m ]
but other say that the matrix transform looks like:
[x, [ m, m, m, m, [x',
y, X m, m, m, m, = y',
z, m, m, m, m, z',
w] m, m, m, m ] w']
I've studied OpenGL for some time, and I beleave the first style is correct, but I see many people use the second style. Is there any difference? Which one should I use?
Quote:[ m, m, m, m,[x, y, z, w] X m, m, m, m, = [x', y', z', w'] m, m, m, m, m, m, m, m ]but other say that the matrix transform looks like:[x, [ m, m, m, m, [x', y, X m, m, m, m, = y', z, m, m, m, m, z', w] m, m, m, m ] w']
Of these two, the first is the technically correct form. The vector is 1x4, and the matrix is a 4x4. In the second case, you cannot multiply a 4x1 and a 4x4, but it's more convenient to write, so the transpose is implied.
However, with OpenGL, the matrix should be on the left, and the vector should be on the right.
Edit: Said matrix where it should have read vector
[Edited by - erissian on May 22, 2008 1:57:29 AM]
Quote:Original post by eastcowboy
Hello there.
I'm reading some articles about matrix these days.
someone says that the matrix transform looks like this:[ m, m, m, m,[x, y, z, w] X m, m, m, m, = [x', y', z', w'] m, m, m, m, m, m, m, m ]
but other say that the matrix transform looks like:[x, [ m, m, m, m, [x', y, X m, m, m, m, = y', z, m, m, m, m, z', w] m, m, m, m ] w']
Your second example isn't correct under any circumstances; in matrix multiplication, the number of columns in the first operand must equal the number of rows in the second operand. This, however, IS correct:
[ m, m, m, m, [x, [x', m, m, m, m, X y, = y', m, m, m, m, z, z', m, m, m, m ] w] w']
The difference is merely one of notation. In the column vector case (which I've just shown), vectors are on the right hand side of the multiplication; in the row vector case (as in your first example) they're on the left. The math is identical; you merely need to transpose the matrix to change it from working with one representation to working with the other representation. OpenGL uses column vectors; this is more out of a desire to conform to prevailing mathematical usage, than because one or the other representation is "better".
Thank you for your reply.
I already know that the second style I wrote is wrong.
So just as erissian said, we treat a vector as a matrix with 4 rows and only 1 columns. Then what is the correct order of transform?
For example, I want to rotate a vector and then translate it. So I calculated two matrix M(R), M(T). The M(R) is for rotate and the M(T) is for translate. What should I do next?
1. M = M(R) X M(T)
V' = M X V
2. M = M(T) X M(R)
V' = M X V
I think the first one is correct, is that right?
I already know that the second style I wrote is wrong.
So just as erissian said, we treat a vector as a matrix with 4 rows and only 1 columns. Then what is the correct order of transform?
For example, I want to rotate a vector and then translate it. So I calculated two matrix M(R), M(T). The M(R) is for rotate and the M(T) is for translate. What should I do next?
1. M = M(R) X M(T)
V' = M X V
2. M = M(T) X M(R)
V' = M X V
I think the first one is correct, is that right?
I could be wrong but I think you'd need to translate to the center first then rotate
M = M(T) X M(R)
then
M = M X M(T) <--- translating to wherever you want
V'=M X V
I dunno :(
M = M(T) X M(R)
then
M = M X M(T) <--- translating to wherever you want
V'=M X V
I dunno :(
Quote:Original post by eastcowboy
Thank you for your reply.
I already know that the second style I wrote is wrong.
So just as erissian said, we treat a vector as a matrix with 4 rows and only 1 columns. Then what is the correct order of transform?
For example, I want to rotate a vector and then translate it. So I calculated two matrix M(R), M(T). The M(R) is for rotate and the M(T) is for translate. What should I do next?
1. M = M(R) X M(T)
V' = M X V
2. M = M(T) X M(R)
V' = M X V
I think the first one is correct, is that right?
I'm going to switch up the notation on you; T for the translation matrix, R for the rotation matrix, and x will be our vector.
If you want to rotate a vector, then you have:
x2=Rx1
If you want to translate that vector:
x3=Tx2
=T(Rx1)
=TRx1
So you can see, the transformations that happen last will be first in the equation.
I see it.
m X v = transpose(v) X transpose(m)
so there's little difference between two styles.
I am a little confused about 'transposed matrix' and the 'row major/column major'. In my code, I use all matrix in 'row major', and the OpenGL uses the 'column-major', this could be a problem for me. but don't worry, I can deal with it. :)
Here's some code I wrote these days.
It is used for matrix calculating.
It uses the 'row-major' to store my matrices. but in the mat4_inverse function, I use the 'col-major' for mistake, and it works well, I don't know why.
m X v = transpose(v) X transpose(m)
so there's little difference between two styles.
I am a little confused about 'transposed matrix' and the 'row major/column major'. In my code, I use all matrix in 'row major', and the OpenGL uses the 'column-major', this could be a problem for me. but don't worry, I can deal with it. :)
Here's some code I wrote these days.
It is used for matrix calculating.
It uses the 'row-major' to store my matrices. but in the mat4_inverse function, I use the 'col-major' for mistake, and it works well, I don't know why.
#include <math.h>void vec4_fromXYZ(vec4 v, float x, float y, float z) { v[0] = x; v[1] = y; v[2] = z; v[3] = 1.0f;}void vec4_fromXYZW(vec4 v, float x, float y, float z, float w) { v[0] = x; v[1] = y; v[2] = z; v[3] = w;}void vec4_copy(vec4 to, vec4 from) { to[0] = from[0]; to[1] = from[1]; to[2] = from[2]; to[3] = from[3];}void mat4_identity(mat4 m) { int i; for(i=0; i<16; ++i) m = 0.0f; m[0] = m[5] = m[10] = m[15] = 1.0f;}void mat4_copy(mat4 to, mat4 from) { int i; for(i=0; i<16; ++i) to = from;}void mat4_multiply(mat4 m1, mat4 m2, mat4 mResult) { int i, j, k; for(i=0; i<4; ++i) { for(j=0; j<4; ++j) { float tmp = 0.0f; for(k=0; k<4; ++k) tmp += m1[i*4+k] * m2[k*4+j]; mResult[i*4+j] = tmp; } }}void mat4_transform(mat4 m, vec4 v, vec4 result) { int i, k; for(i=0; i<4; ++i) { float tmp = 0.0f; for(k=0; k<4; ++k) tmp += m[i*4+k] * v[k]; result = tmp; }}void mat4_translate(mat4 m, float x, float y, float z) { mat4 transform = { 1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1 }; mat4 tmp; mat4_multiply(m, transform, tmp); mat4_copy(m, tmp);}void mat4_rotateX(mat4 m, float theta) { mat4 transform = { 1, 0, 0, 0, 0, cosf(theta), -sinf(theta), 0, 0, sinf(theta), cosf(theta), 0, 0, 0, 0, 1 }; mat4 tmp; mat4_multiply(m, transform, tmp); mat4_copy(m, tmp);}void mat4_rotateY(mat4 m, float theta) { mat4 transform = { cosf(theta), 0, sinf(theta), 0, 0, 1, 0, 0, -sinf(theta), 0, cosf(theta), 0, 0, 0, 0, 1 }; mat4 tmp; mat4_multiply(m, transform, tmp); mat4_copy(m, tmp);}void mat4_rotateZ(mat4 m, float theta) { mat4 transform = { cosf(theta), -sinf(theta), 0, 0, sinf(theta), cosf(theta), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; mat4 tmp; mat4_multiply(m, transform, tmp); mat4_copy(m, tmp);}void mat4_transpose(mat4 m, mat4 result) { int i, j; for(i=0; i<4; ++i) for(j=0; j<4; ++j) result[i*4+j] = m[j*4+i];}static float det3(float* m, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9) { return m[a1] * m[a5] * m[a9] + m[a2] * m[a6] * m[a7] + m[a3] * m[a4] * m[a8] - m[a3] * m[a5] * m[a7] - m[a2] * m[a4] * m[a9] - m[a1] * m[a6] * m[a8];}void mat4_inverse(mat4 m, mat4 result) { float d = +m[ 0] * det3(m, 5, 9, 13, 6, 10, 14, 7, 11, 15) -m[ 4] * det3(m, 1, 9, 13, 2, 10, 14, 3, 11, 15) +m[ 8] * det3(m, 1, 5, 13, 2, 6, 14, 3, 7, 15) -m[12] * det3(m, 1, 5, 9, 2, 6, 10, 3, 7, 11); d = 1.0f / d; result[ 0] = d * det3(m, 5, 9, 13, 6, 10, 14, 7, 11, 15); result[ 1] = -d * det3(m, 1, 9, 13, 2, 10, 14, 3, 11, 15); result[ 2] = d * det3(m, 1, 5, 13, 2, 6, 14, 3, 7, 15); result[ 3] = -d * det3(m, 1, 5, 9, 2, 6, 10, 3, 7, 11); result[ 4] = -d * det3(m, 4, 8, 12, 6, 10, 14, 7, 11, 15); result[ 5] = d * det3(m, 0, 8, 12, 2, 10, 14, 3, 11, 15); result[ 6] = -d * det3(m, 0, 4, 12, 2, 6, 14, 3, 7, 15); result[ 7] = d * det3(m, 0, 4, 8, 2, 6, 10, 3, 7, 11); result[ 8] = d * det3(m, 4, 8, 12, 5, 9, 13, 7, 11, 15); result[ 9] = -d * det3(m, 0, 8, 12, 1, 9, 13, 3, 11, 15); result[10] = d * det3(m, 0, 4, 12, 1, 5, 13, 3, 7, 15); result[11] = -d * det3(m, 0, 4, 8, 1, 5, 9, 3, 7, 11); result[12] = -d * det3(m, 4, 8, 12, 5, 9, 13, 6, 10, 14); result[13] = d * det3(m, 0, 8, 12, 1, 9, 13, 2, 10, 14); result[14] = -d * det3(m, 0, 4, 12, 1, 5, 13, 2, 6, 14); result[15] = d * det3(m, 0, 4, 8, 1, 5, 9, 2, 6, 10);}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement