PDA

View Full Version : Using a matrix to generate a new vector position


imikedaman
2006.07.16, 03:52 PM
Okay, basically I'm just trying to calculate the new location for a point after applying a few translates and rotates to the modelview matrix in OpenGL. Here's what I have:

The matrix, by using glGetFloatv(GL_MODELVIEW_MATRIX, mat)
A vector, which is just an (x, y, z) coordinate

Normally I'd just multiply the vector by the matrix, but the matrix is 4x4 in OpenGL and my vector is 3x1. How can I calculate the new position for the vector using that matrix?


----
Like say for example my vector is (0, 0, 0), and I run these transformations:
glTranslatef(0, 4, 0)
glRotatef(90, 0, 0, 1) // rotate to the right 90 degrees
glTranslatef(3, 0, 0)

How could it calculate that the new vector position is (3, 4, 0)?


Thanks in advance!

Holmes
2006.07.16, 04:20 PM
Okay, basically I'm just trying to calculate the new location for a point after applying a few translates and rotates to the modelview matrix in OpenGL. Here's what I have:

The matrix, by using glGetFloatv(GL_MODELVIEW_MATRIX, mat)
A vector, which is just an (x, y, z) coordinate

Normally I'd just multiply the vector by the matrix, but the matrix is 4x4 in OpenGL and my vector is 3x1. How can I calculate the new position for the vector using that matrix?


----
Like say for example my vector is (0, 0, 0), and I run these transformations:
glTranslatef(0, 4, 0)
glRotatef(90, 0, 0, 1) // rotate to the right 90 degrees
glTranslatef(3, 0, 0)

How could it calculate that the new vector position is (3, 4, 0)?


Thanks in advance!

OpenGL uses what is called a homogeneous coordinate system. Which (pardon my bastardization) is like tacking on an extra dimension to points. The idea can be pretty clearly illustrated when you embed a 2D plane in 3-space, but when you're embedding 3-space into 4-space like OpenGL does, it's pretty hard to visualize or illustrate. But anyway, here is how it works:

In homogeneous coordinates the point (x, y, z) can be represented as (ax, ay, az, a) for any non-zero constant a. In other words, the points (ax, ay, az, a) and (bx, by, bz, b) are equal if a and b are non-zero real numbers.

In order to multiply your vector by the matrix you must first represent it as a homogeneous point. So if your vector is (x, y, z), you can represent it as (x, y, z, 1). Multiply this vector by the matrix. What you'll get is (x_prime, y_prime, z_prime, c). In order to turn the resultant vector into a normal 3D vector you need to divide each component by c so that you get (x_prime / c, y_prime / c, z_prime / c, 1). Your answer is then (x_prime / c, y_prime / c, z_prime / c).

EDIT: Actually, do you have to divide by c? I just realized that with what OpenGL uses the modelview matrix for, you might not have to (c might always be 1).

imikedaman
2006.07.16, 04:54 PM
Since w is always 1 from what I can tell, doing that is functionally equivalent to what I was previously doing, which is just adding the last column directly to the x, y, and z values for the vector, since that's where the translation values apparently go. However, that doesn't seem to work right. :-/

Unless there's a glitch somewhere else in my code... I better go check.

unknown
2006.07.16, 05:07 PM
... since that's where the translation values apparently go.
that doesn't mean that you should do anything differently, its simply a 4x4 matrix multiplied by a 4x1 matrix.

Holmes
2006.07.16, 05:07 PM
Since w is always 1 from what I can tell, doing that is functionally equivalent to what I was previously doing, which is just adding the last column directly to the x, y, and z values for the vector, since that's where the translation values apparently go. However, that doesn't seem to work right. :-/

Unless there's a glitch somewhere else in my code... I better go check.

Maybe you aren't grabbing the entries of the matrix correctly?
m[12], m[13], and m[14] should be the translational entries of the modelview matrix. m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], and m[10] are the affine entries of the matrix.

imikedaman
2006.07.16, 05:11 PM
It's definitely a bug elsewhere in the code, and not with how I was composing the transformations. After running a simple test (start at the origin, translate up 4 units, rotate right 90 degrees, translate "up" 3 units), it got the correct answer of (4, 3, 0). And now begins the long and tedious process of figuring out where I messed up. :zzz:

EDIT: Yep, I was using 12, 13, and 14 for the translation entries. Thanks for your help. :)

imikedaman
2006.07.16, 05:17 PM
Aha, that wasn't so long, nor was it particularly tedious. It turns out I was effectively calling glTranslate in the wrong place, making everything increasingly distored as everything propagated down the recursive function. Now everything seems to be working fine!