• Create Account

Banner advertising on our site currently available from just \$5!

# Projected area of triangle

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

11 replies to this topic

### #1enigmagame  Members   -  Reputation: 138

Like
0Likes
Like

Posted 06 March 2008 - 10:05 AM

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!

### #2CodeMunkie  Members   -  Reputation: 805

Like
0Likes
Like

Posted 06 March 2008 - 10:33 AM

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)

### #3Álvaro  Crossbones+   -  Reputation: 14878

Like
0Likes
Like

Posted 06 March 2008 - 03:43 PM

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|

### #4enigmagame  Members   -  Reputation: 138

Like
0Likes
Like

Posted 06 March 2008 - 10:39 PM

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!

### #5haegarr  Crossbones+   -  Reputation: 5231

Like
0Likes
Like

Posted 06 March 2008 - 11:48 PM

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.

### #6enigmagame  Members   -  Reputation: 138

Like
0Likes
Like

Posted 07 March 2008 - 03:11 AM

Quote:
 Original post by haegarrBTW, 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...

### #7haegarr  Crossbones+   -  Reputation: 5231

Like
0Likes
Like

Posted 07 March 2008 - 04:46 AM

Quote:
Original post by enigmagame
Quote:
 Original post by haegarrBTW, 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.

### #8enigmagame  Members   -  Reputation: 138

Like
0Likes
Like

Posted 07 March 2008 - 05:25 AM

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!

### #9haegarr  Crossbones+   -  Reputation: 5231

Like
0Likes
Like

Posted 07 March 2008 - 06:50 AM

Quote:
 Original post by enigmagameI 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 enigmagameSo 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 thenM*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:
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.

### #10enigmagame  Members   -  Reputation: 138

Like
0Likes
Like

Posted 09 March 2008 - 11:09 PM

Quote:
 Original post by haegarrAssuming 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 haegarrTaking all this together, I'd say thatglGet(GL_MODELVIEW_MATRIX, M);glGet(GL_PROJECTION_MATRIX, P);V1' = P*M*V1would 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.
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!

### #11haegarr  Crossbones+   -  Reputation: 5231

Like
0Likes
Like

Posted 10 March 2008 - 01:24 AM

On how to convert the "vector" into a matrix (you haven't written how you've done it, so I mention it here): OpenGL not only uses column vectors but also column major order for their linear matrix storage. That means that a sequence of coefficients
c00 c01 c02 c03 c04 ... c15
as is returned by glGet, has to be interpreted as a matrix like in
[ c00 c04 c08 c12 }[ c01 c05 c09 c13 }[ c02 c06 c10 c14 }[ c03 c07 c11 c15 }

The algorithm you've outlined above seems me correct so far. However, there are many possibilities to build bugs into the code, of course. It may be best to check the results of the various steps for plausibility. E.g. generate a quad in front of the camera, the face perpendicular and centric to the line-of-view. Then look at the matrices when freshly returned by glGet. Do they look as expected? And after multiplying the vertex positions, are the projected positions also okay? Simplify the test cases as much as possible for the first tests, e.g. let the camera rest at 0 and don't change its looking direction. Use I as model matrix and compute the quad's vertices as they were in global co-ordinates.

I don't assume so, but it may be that the one or other matrix needs to be inverted. Looking at simplified test cases may expose such algorithmic errors earlier or later, also it may expose coding errors.

### #12enigmagame  Members   -  Reputation: 138

Like
0Likes
Like

Posted 21 March 2008 - 04:07 AM

Ok! It runs!
Thanks!!

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS