How to calculate a particular transformation matrix?

Dear All:

I post this question in the OpenGL:Beginning section, but no one replies. I hope to get some helps in this section.

I am using OpenGL under Window XP for MFC application. I draw a “flat plan” (like one face of a box), the normal vector of this plan is known (since it is a flat plan), but this normal vector is not parallel to any of the x, y or z axis. I would like to know: if this plan is drawn, and if the user use the mouse to rotate this plan, since I know the normal vector of this plan, would it possible to calculate the transformation matrix so that this plan will “face” exactly the user (ie, the normal vector of this plan will point toward to the window screen)?

Thanks for any hints.

Hello,

I don’t really understand you problem. You said that after the user rotates the plane, the normal should face him… If he can rotate the plane then the normal will move, as the plane, after the will of the user.
If you want to rotate the plane, who’s normal faces an arbitrary direction, so that it will face the user, here’s one exemple:

  • translate the plane in the origin
  • get the angle between the plane normal and view vector (theta = arccos(n.v)), and rotate the plane by -theta around Z axis (suposing that the view vector is paralel with Z)
  • translate back the plane in it’s original position

I hope this will help.

Wolf.

Thanks for your reply. I appreciate.

I don’t really understand you problem. You said that after the user rotates the plane, the normal should face him…
Ok, say, suppose I have draw a finite plan of 2x + 3y + 5z = 0 (x,y,z are bounded). The user use the mouse to rotate the sence (the normal of the plan is still the same, but point to somewhere in the sapce), if I have a hot key, say F1. How can I do if the F1 is pressed, then the normal of this plan is pointed directed to the windor screen (hence, point to the user)?

If he can rotate the plane then the normal will move, as the plane, after the will of the user.
If you want to rotate the plane, who’s normal faces an arbitrary direction, so that it will face the user, here’s one exemple:

  • translate the plane in the origin
  • get the angle between the plane normal and view vector (theta = arccos(n.v)), and rotate the plane by -theta around Z axis (suposing that the view vector is paralel with Z)
  • translate back the plane in it’s original position

How can I “get the angle between the plane normal and view vector (theta = arccos(n.v)),” ?

Thanks for your time and help.

Hello again.

There is a vector operation called the dot product, or internal product. Supose we have 2 vectors v1[x1, y1, z1] and v2[x2, y2, z2].
Let ‘.’ be the dot product operator.

v1 . v2 = x1x2 + y1y2 + z1*z2
and also
v1 . v2 = ||v1|| * ||v2|| * cos(theta),
where ||v1|| and ||v2|| are the norms of the vectors, and ‘theta’ is the angle between the vectors.

Now, if you need the angle between v1 and v2, you first get the cosinus of the angle:

cos(theta) = (v1 . v2) / (||v1|| * ||v2||)

If v1 and v2 are normalized ( lenght(v1) = lenght(v2) = 1), then you ecuation is:

cos(theta) = v1 . v2

Next you must get the angle itself, and you do that by performing the inverse operation of the cosinus: arccos.

theta = arcos( cos(theta) ) = arcos ( v1 . v2)

…^
v1/
…/
./ -->theta
/---------> v2

I hoppe this will help you in you work.

Best regards,
Wolf.

Thanks,

I did not make my question clear – I know how to get the angle in between two vectors. The thing I don’t know is – we need two vectors, one is the normal vector of the plan, this is what I know since I create the plan, but how to get the view vector normal to the screen? Especially after the user arbitrary rotation and translation and zoom in/out? What OpenGL command to get the view vector normal to the screen?

Thanks again.

What do you use to set the camera direction in the first place?

Exactly. That’s where you get the normal vector from. From those angles.

(positive) scale and translation do not influence the viewing direction so you can ignore those.

Thanks for reply.

I simply use the common gl commands, like the following:

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(Winleft, Winright, Winbottom, Wintop, Winnear, Winfar);

glMatrixMode(GL_MODELVIEW);
glDrawBuffer(GL_BACK);

But these are the commands used in the beginning, don’t forget THE USER CAN ROTATATE THE PLAN TO ANY ANGLE (the transformation chaged after the translation).

I can get the transformation matrix by
glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);

But what is the normal vector of the viewing plan?

Thanks for your time!

The user does not glRotate and glTranslate. You do.

So keep track of the camera’s position and rotation.

Go find some matrix tutorials if you need them.
E.g.: http://nehe.gamedev.net/data/articles/article.asp?article=02

PS: in principle the normal vector should be the Y unit-vector of the matrix.

get the gl transformation matrix and extract the rotation from that

Thanks for replies.

The user does not glRotate and glTranslate. You do.

So keep track of the camera’s position and rotation.

Go find some matrix tutorials if you need them.
E.g.: http://nehe.gamedev.net/data/articles/article.asp?article=02

I check the link you pointed out, thanks. But it is very basic matrix operation. I already know it. The problem is the user might rotate the scene with x, y, and z at the same time (and of course, “my program” (I) rotate it), and you see even the scale command effect the 4 by 4 matrix (ie, when do the scale, the matrix a11 change, but when rotate with Y, the a11 also change, thus, when you get the current transformation matrix by

glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);

We are getting 4 by 4 matrix (or 16 double digits) – which is a combination of a serial of rotate and scale operation (or even the lookat command will change the content of the matrix).

MY Question seems now – after getting the matrix, what is the normal vector of the viewing plan??

get the gl transformation matrix and extract the rotation from that
Thanks, but in my previous post, I mentioned that I know how to get the matrix by

glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);
But what is the normal vector of the viewing plan?

Hello there
The problem that you have posted here is a technique called billboarding have a look at nehe’ site for details or have a google search on it
Thanx
MMMovania.

Hi,

Since you already know origin and plane normal, the easiest thing for you is to use gluLookAt to define a new model_view matrix. For this func, you already have centerx/y/z(which is your plane origin), up vector x/y/z(0,1,0), to calculate eyex/y/z, you can use

center - plane_normal * distance(which is usually the distance b/w viewer and your model center)