Projected area of triangle

Started by
10 comments, last by enigmagame 16 years, 1 month ago
Hi all! I must calculate the projected area of triangle I've 3 points with coordinates x,y,z. I retrive the projection matrix with the function glGetFloatv(GL_PROJECTION_MATRIX, m), and i multiply this matrix for my triangle points. It's correct? Now, how i can find the triangle area? Thanks!
Advertisement
Project the points of your triangle (A, B, C):

A' = m * A
B' = m * B
C' = m * C

u = B' - A'
v = C' - A'

area = 1/2 * |u x v|

(x is vector cross product)
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
That doesn't seem right, CodeMunkie. The projection matrix is a 4x3 matrix. You need to put a 1 as a fourth coordinate for each point. The resulting projected points now have 3 coordinates, and you need to divide by the last coordinate to turn them into meaningful 2D points.

Now that you have 3 2D points, the cross product that you are proposing isn't really defined in 2D. You can add a third coordinate that is 0 and do it the way you described (now in 3D), or you can just compute the area as the absolute value of

|x1 y1 1|
|x2 y2 1| * 1/2
|x3 y3 1|

With glGetFloatv(GL_PROJECTION_MATRIX, m) function i have a 4x4 matrix, not a 4x3 matrix.
I put a 1 as fourth coordinate for each point, then for each point i do the product between my 4x4 matrix and my point vector (with four rows). The result is a new point vector (with four rows).
Now, what i do?
Thanks!
Converting from a homogeneous position vector to an affine position vector requires the homogeneous co-ordinate to be 1. If it isn't, dividing the vector by its homogeneous co-ordinate does the trick.

Then simply drop the homogeneous co-ordinate to yield in the equivalent affine vector. Now you still have 3 co-ordinates left, but you can ignore the z co-ordinate if you're not interested in a depth value. Hence all you have to do is to pick out the x and y co-ordinates.

BTW, be aware that the PROJECTION matrix does include neither local-to-global nor global-to-eye/camera transformations. So the vertex co-ordinates mentioned in the OP have to already be given relative to the camera's co-ordinate frame.
Quote:Original post by haegarr
BTW, be aware that the PROJECTION matrix does include neither local-to-global nor global-to-eye/camera transformations. So the vertex co-ordinates mentioned in the OP have to already be given relative to the camera's co-ordinate frame.

Don't understand this point...
Quote:Original post by enigmagame
Quote:Original post by haegarr
BTW, be aware that the PROJECTION matrix does include neither local-to-global nor global-to-eye/camera transformations. So the vertex co-ordinates mentioned in the OP have to already be given relative to the camera's co-ordinate frame.

Don't understand this point...

Normally geometry of a mesh is given w.r.t. a co-ordinate system especially for that mesh. Now, the mesh as a whole is rotated to the wanted orientation and located in the world. This in summary is what is called the local-to-global transformation. In OpenGL this is what makes the MODEL portion of the MODELVIEW matrix. Let's name it M.

Normally you'll look into the world by a camera. The camera, normally handled like any other object in the world, also has a local-to-global transformation. However, what you want is to see the scene from the camera, not from the world. Hence you are interested in fact in the inverse of the camera's co-ordinate frame (i.e. its global-to-local transformation). This transformation makes the VIEW portion of OpenGL's MODELVIEW matrix. Let's name it V, where
V := C-1
if C denotes the camera's frame.

The PROJECTION matrix is applied to the geometry after it is transformed to be camera local. If the projection is named P, then the overall transformation normally looks like something like
P * V * M
(using column vectors, as OpenGL does). So you have to consider this if your geometry is not already give w.r.t. the camera's local co-ordinate frame.
I have positioned the model with glTranslate() function, and i setup the camera with the gluLookAt() function.
So i must multiply each triangles point for the M (MODELVIEW MATRIX) and then for the P (PROJECTION MATRIX)?
For example if V1, V2, V3 is triangle points:
glGet(GL_MODELVIEW_MATRIX, M);
glGet(GL_PROJECTION_MATRIX, P);
and then
M*P*V1 = V1'
M*P*V2 = V2'
M*P*V3 = V3'
It's correct, or i have forgot the view transformation?
Thanks!
Quote:Original post by enigmagame
I have positioned the model with glTranslate() function, and i setup the camera with the gluLookAt() function.
Assuming that these steps are done with the GL_MODELVIEW_MATRIX being active, then you've specified said MODELVIEW matrix. But, of course, you have to invoke the camera settings (e.g. gluLookAt) before you invoke the model settings, or else things will go wrong. See below for why.

Quote:Original post by enigmagame
So i must multiply each triangles point for the M (MODELVIEW MATRIX) and then for the P (PROJECTION MATRIX)?
For example if V1, V2, V3 is triangle points:
glGet(GL_MODELVIEW_MATRIX, M);
glGet(GL_PROJECTION_MATRIX, P);
and then
M*P*V1 = V1'
M*P*V2 = V2'
M*P*V3 = V3'
It's correct, or i have forgot the view transformation?
The view transformation is part of the MODELVIEW transformation, and you get both in combination if you invoke glGet(GL_MODELVIEW_MATRIX, M). Some people think it is nasty, but OpenGL does it that way. However, you've forgotten about the fact that mathematically column vectors and row vectors have to be distinguished clearly. OpenGL uses column vectors (as opposed to D3D, which uses row vectors). A matrix-vector product with column vectors is written as
M * v
w/ M denoting the matrix and v the vector. Notice that the vector is on the right of the matrix! Remember furthur that matrix multiplication is not commutative, that means generally
M1 * M2 != M2 * M1
Order of matrices is very important!

With these aspects in mind, your formula
M*P*V1 = V1'
is wrong, since it means "transform the vertex with P (the projection matrix), and transform the result with M (the modelview matrix)". Please compare this with the formula i've posted in my previous answer:
P * V * M
or, with the combined MODELVIEW matrix (and hence closer to your style)
P * VM
which means "transform the (here not shown) vertex with the modelview matrix, and transform the result with the projection matrix".

Now coming back to your sentence I've cited at first in this post, it is important that after clearing the MODELVIEW matrix, you first have to set the camera (i.e. invoke gluLookAt), and after that you have to set the model transformation:
glLoadIdentity();
gluLookAt(...); // camera
glTranslate(...); // model
since this order of invocations is equivalent to
I * V * M
what builds the MODELVIEW matrix correctly.

Taking all this together, I'd say that
glGet(GL_MODELVIEW_MATRIX, M);glGet(GL_PROJECTION_MATRIX, P);V1' = P*M*V1
would be the solution you're looking for. Notice please that I assume here that your vector API works with column vectors, since your "code snippet" has shown the vector on the right side.
Quote:Original post by haegarr
Assuming that these steps are done with the GL_MODELVIEW_MATRIX being active, then you've specified said MODELVIEW matrix. But, of course, you have to invoke the camera settings (e.g. gluLookAt) before you invoke the model settings, or else things will go wrong. See below for why.

Yes, yes, first i set the camera (with gluLookAt function) and then i invoke the model settings.

Quote:Original post by haegarr
Taking all this together, I'd say that
glGet(GL_MODELVIEW_MATRIX, M);glGet(GL_PROJECTION_MATRIX, P);V1' = P*M*V1
would be the solution you're looking for. Notice please that I assume here that your vector API works with column vectors, since your "code snippet" has shown the vector on the right side.

I must calculate for each triangle a weight factor, where the weight factor is: (area of projected triangle)/(surface area of triangle), and then i must render each triangle, flat filled, with intensity proportional to the weight factor.
I've tried with this model, and with your indication for the projected area.
http://img156.imageshack.us/img156/7909/scimmiahx4.jpg
But for me, the results is wrong...
I think I make mistakes to calculate the projected area.
I've made this:
glGet(GL_MODELVIEW_MATRIX, M);glGet(GL_PROJECTION_MATRIX, P);

M and P is a vector, then with a function I create two 4x4 matrix with M and P values. I've multiplied P*M. I've added a fourth co-ordinate (1) to each vertex.
I've multiplied the results of P*M for each vertex (A,B,C) so:
- A' = P*M*A
- B' = P*M*B
- C' = P*M*C
Then i've divided each x and y vertex co-odrinate for the fourth co-ordinate and i set the z co-ordinate to 0.
I've calculated this vectors:
- V1 = B - A
- V2 = C - A
then i made the cross product of V1 and V2 and i return half of magnitude.
It's wrong?
Thanks!

This topic is closed to new replies.

Advertisement