confused about matrix and transform

Started by
5 comments, last by eastcowboy 15 years, 11 months ago
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?
Advertisement
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]
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
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 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 :(
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.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
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.
#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