matrix mania

Started by
9 comments, last by JuNC 18 years, 9 months ago
Previously, I asked about how to figure out the offset from the origin that you would be at after a series of glTranslatef and glRotate3f operations. This is what we came up with: GLfloat matrix[16]; glGetFloatv(GL_MODELVIEW_MATRIX, matrix); float x = matrix[12]; float y = matrix[13]; float z = matrix[14]; This seems to work. However, let's say that you throw in glScalef operations into the mix. How do you compute x, y, and z then? I'm pretty sure you need to divide x, y, and z by other numbers in the matrix, but I'm not really sure which ones. Mike C. http://www.coolgroups.com/zoomer/
Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
Advertisement
This is the matrix (from opengl perspective)- this is how it will read in a 4x4 matrix or an array of size 16

a0 a4 a8 a12
a1 a5 a9 a13
a2 a6 a10 a14
a3 a7 a11 a15

Scaling comonent = a0, a5, a10,
Translation component = a12, a13, a14, a15(which is w)

So to translate you modify 12, 13, 14 and to scale you modify 0, 5, 10.And the x, y, z will still be at 12, 13, 14 it won't change. Also remember when you scale a model, you scale with respect to its origin so its translation component will more or less be the same.

The more applications I write, more I find out how less I know
Interesting. So, let's say I want to transfrom x, y, and z by this. Is this right?

x = x*matrix[0] + y*matrix[4] + z*matrix[8] + matrix[12];
y = x*matrix[1] + y*matrix[5] + z*matrix[9] + matrix[13];
z = x*matrix[2] + y*matrix[6] + z*matrix[10] + matrix[14];


Mike C.
http://www.coolgroups.com/zoomer/

Quote:Original post by CRACK123
This is the matrix (from opengl perspective)- this is how it will read in a 4x4 matrix or an array of size 16

a0 a4 a8 a12
a1 a5 a9 a13
a2 a6 a10 a14
a3 a7 a11 a15

Scaling comonent = a0, a5, a10,
Translation component = a12, a13, a14, a15(which is w)

So to translate you modify 12, 13, 14 and to scale you modify 0, 5, 10.And the x, y, z will still be at 12, 13, 14 it won't change. Also remember when you scale a model, you scale with respect to its origin so its translation component will more or less be the same.


Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
Actually, I guess it would be more like this:

newx = x*matrix[0] + y*matrix[4] + z*matrix[8] + matrix[12];
newy = x*matrix[1] + y*matrix[5] + z*matrix[9] + matrix[13];
newz = x*matrix[2] + y*matrix[6] + z*matrix[10] + matrix[14];

But, it still doesn't seem to behave properly.

Mike C.
http://www.coolgroups.com/zoomer/
Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
My matrix math is a little rusty, but I'll give this a try..

Your x,y,z tuple can be treated just like a 3x1 matrix. To transform that matrix by your 4x4 matrix, you simply apply the matrix multiplication rules.

However, you can't multiply a 4x4 matrix by a 3x1 matrix, so we'll add a 'w' to the end, giving us [x,y,z,w] (and have the value of 'w' be '1')

So.
Assume matrix B = |x|           |y|           |z|           |w|matrix M = |a0 a4 a8  a12|            |a1 a5 a9  a13|           |a2 a6 a10 a14|           |a3 a7 a11 a15|M*B = [Mrow1.Bcol1,Mrow2.Bcol1, Mrow3.Bcol1, Mrow4.Bcol](where "." means "dot product")    = |x=(a0*x+a4*y+a8*z+a12*w)|      |y=(a1*x+a5*y+a9*z+a13*w)|      |z=(a2*x+a6*y+a10*z+a14*w)|      |w=(a3*x+a7*y+a11*z+a15*w)|

Of course, if you don't want the 'w' in your vector, you can normalize it out by dividing the other values in the vector by w:
[x/w,y/w,z/w]

I'm pretty sure that's how it works.

[Edited by - pragma Fury on July 9, 2005 10:02:15 AM]
Well directx or opengl, matrix math remains the same. Its plain simple maths. I dont remember if applying a rotation matrix affects the scaling component. I suppose it should not.

The more applications I write, more I find out how less I know
Quote:Original post by pragma Fury
Of course, if you don't want the 'w' in your vector, you can normalize it out by dividing the other values in the vector by w:
[x/w,y/w,z/w]

I'm pretty sure that's how it works.


If you don't want a 'w' you can always use a 4x3 matrix to do your work.



The more applications I write, more I find out how less I know
Quote:Original post by CRACK123
Well directx or opengl, matrix math remains the same. Its plain simple maths.


Except that opengl uses column-vectors and directx uses row-vectors. Also, directX matrix is the transpose of the OpenGL matrix.
So instead of V*M (where V is your vector matrix) you use M*V in OpenGL


Quote:I dont remember if applying a rotation matrix affects the scaling component. I suppose it should not.


Except that it will, for the same reason a Y-axis rotation matrix affects a z-axis rotation matrix. It won't affect the translation component, however.
If you want a matrix that scales & rotates, you must create them as seperate matricies and concatenate them.

Quote:If you don't want a 'w' you can always use a 4x3 matrix to do your work.

True, except that then you lose your translation component.. not an issue if we don't care about that, of course. Edit: Actually, if you use a 4x3, you'd end up with a "w" component anyway, so I'm assuming you meant 3x3.

In any case, for mike74's benefit, let's do an example, shall we?
Let's say you have xyz coordinates of (1,2,5) and you want to scale that on all axis by 2, and translate it along the X by 1. Obviously, the output will be (3,4,10).
V=|1|  |2|  |5|  |1|M=|2 0 0 1|  |0 2 0 0|  |0 0 2 0|  |0 0 0 1|x' = 2*1+0*2+0*5+1*1 = 2+0+0+1 = 3y' = 0*1+2*2+0*5+0*1 = 0+4+0+0 = 4z' = 0*1+0*2+2*5+0*1 = 0+0+10+0 = 10w' = 0*1+0*2+0*5+1*1 = 0+0+0+1 = 1

So, our new coordinates are (3,4,10,1) .. and to get rid of the 'w' value: (3/1,4/1,10/1) = (3,4,10)

[Edited by - pragma Fury on July 9, 2005 11:41:08 AM]
Quote:Original post by pragma Fury
Except that opengl uses column-vectors and directx uses row-vectors. Also, directX matrix is the transpose of the OpenGL matrix.
So instead of V*M (where V is your vector matrix) you use M*V in OpenGL


Actually what I meant was how the multiplication happens with respect to matrices(ignoring directx and opengl or the way things are stored) is the same.

Quote:Original post by pragma Fury
Except that it will, for the same reason a Y-axis rotation matrix affects a z-axis rotation matrix. It won't affect the translation component, however.


Checked it, the scaling component and rotation component clashes in some/many cases.

Quote:
True, except that then you lose your translation component.. not an issue if we don't care about that, of course.


Ofcourse in directx you would lose the 4th row. I was just simplifying. However losing the translation component is not a big deal as you can just add it to the vector using a vector itself.
The more applications I write, more I find out how less I know
When exactly is the w component not going to be equal to 1?

So, I'm asking when this is necessary:
x=x/w;
y=y/w;
z=z/w;

Thanks.

Mike C.
http://www.coolgroups.com/zoomer/
Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/

This topic is closed to new replies.

Advertisement