Still Rotations...

OK guys, here is another one (actually it is still related to my 3DS-Max-like rotations but I made the question clearer…).

Let’s say that in my engine, all the objects are positioned with :

glTranslatef(X,Y,Z); (you can forget this one for the question !)
glRotatef(aZ,0,0,1);
glRotatef(aY,0,1,0);
glRotatef(aX,1,0,0);

No need to discuss the efficiency of the method : that’s what 3DS-Max R3 uses ; when you specify 3 angles around X,Y and Z (in Absolute:World), it uses these rotations to build the final rotation matrix…

Now, say I have a transformation matrix M (let’s say it features no translation ; so we can forget the glTranslatef in my code and get back to a 3x3 matrix).
Let’s say this matrix is the product of several rotations (yeah ! for sure !).

My question is : how do I find the angles aX,aY and aZ that will build the exact same matrix ???

I have been to several maths web sites but they do not explicitely answer this one…

Has anyone got the slightest idea ?

Please, HELP !

Best Regards.

Eric

Uhm, really dunno if this works… but an idea that struck me, is the following.

Take a paper and a pencil (or whatever you might want to use to write), and set up three matrices with SYMBOLIC values, and multiply them in proper order. Then you get a “total rotation matrix” build up of symbols (variables), where you insert your values and calculate a single rotation matrix (which you can upload with glLoadMatrix). When you got that matrix, maybe you can identify your symbolic matrix with the actual rotation matrix you got. From there, you should get an equation system. Solve this equation system and you should have your three rotation angles.

It really helps if you got a maths program that can handle symbols. I know it’s possible to perform quite advanced maths with symbolic matrices in Matlab.

Hi Bob !

Well, I have already thought about doing that but with no success… The main problem is that you won’t obtain a linear system easily with all the cos/sin on aX,aY,aZ…

As far as I remember, it is possible to obtain something linear with the atan(aX/2),…,atan(aZ/2) but I would not bet on that !

What I am pretty sure about, is that there are some calculations involving the trace and det of the matrix… Shame I do not have my maths courses in England… (I am French…)

Your idea about using MatLab sounds really interesting and I am going to have a go at it right now (that is, if my company has got MatLab somewhere !!!).

Thanks for your input !

Regards.

Eric

Yeah, I know you will get a non-linear system, and that it won’t be that easy to solve. But maybe it’s possible to rewrite some expressions to other kind of trig functions, like sin(x)^2=1-cos(x)^2… you know. Maybe something like that is possible… but it’s probably going to make it worse I suppose
Luckily, you only have to solve it once. When it’s solved, all you have to do is place the calculations in your code (thank god we don’t have to do the identification in realtime).

Launched MatLab to have a look at the resulting matrices/equations, and maybe try to solve them with MatLab. But there was a new version installed, and this copy didn’t have the library for symbolic matrices

Hi again!

Well, I think it would be more useful to use things such as :

cos(a+b)=cos acos b-sin asin b;

or

sin 2a=2sin acos a

I have to find something…

Thanks !

Eric

Yep, found the solution !

It’s actually very simple…

For those who are interested :

void C_Base_Entity::GetRotationAngles(float& X,float& Y,float& Z)
{

if ((fabs(m_TransformMatrix.Matrix[6])<1E-6)&&(fabs(m_TransformMatrix.Matrix[1])<1E-6))
{
X=0;
Y=0;
}
else
{
X=atan2(m_TransformMatrix.Matrix[6],m_TransformMatrix.Matrix[10]);
Z=atan2(m_TransformMatrix.Matrix[1],m_TransformMatrix.Matrix[0]);
}
float cZ=cos(Z);
float cY;
if (fabs(cZ)>5E-4)
cY=m_TransformMatrix.Matrix[0]/cZ;
else
cY=m_TransformMatrix.Matrix[1]/sin(Z);
Y=atan2(-m_TransformMatrix.Matrix[2],cY);

}

Simple, isn’t it ?!??!??

Thanks a LOT Bob !

Eric

Ooh, nice one!

How did you manage to do it? Brute force calculations by hand or what?
Anyway, thought it would be a bit more complex that that

Actually, I found a copy of Matlab running around…

I have set up all the basic rotation matrix using symbols (RotX,RotY,RotZ) and had a look at the product (actually, I had done it already by hand but I wanted to check… It’s so easy to make a mistake after the first product !).

Then, the resulting matrix was pretty easy to use but you always have this problem of :

a=sin b does not mean b=asin(a).
The real thing is :
a=sin b means b=asin(a) or b=pi-asin(a) !
That is why you need the cos (and not the absolute value of the cos !).

Then, I remembered this atan2 function that basically uses both sin and cos to find in which quadrant of the unit circle the angle is… Then you have your result between -pi and pi !!!

When you look at the matrix, you can see how easy it is to use atan2…

The first “if” statement simply avoids your X and Z to jump from 0 to 180 when you rotate around Y (just comment those lines and you will see the result !).

That is because atan2(y,x) will give two different results when y=0 :
if x>0, atan2=0;
if x<0, atan2=180;
I am using degrees but atan2 gives radians…

So, all in all, that is a good mix that does exactly what I want !!!

I now have an OpenGL MFC framework that works like 3DS Max : I can select/translate/rotate/scale objects exactly like in 3DS…

When you select an object, the axes appear and stay the same size wherever the view point is… Things like that !

The main problems I had and solved were :

  • How to have non-scaling objects ? These are these objects that always have the same size independantly of the view point (in 3DS, this is used for axes/lights/cameras).
  • How to rotate an object by offset or absolute position around X,Y,Z…
  • How to do spherical billboards (that was for the letters X,Y and Z on the axes). I could not use the technique that was explained in the previous topic (I am not drawing a quad but a WYSIWYG font !).

Although these things seemed quite easy to solve, they were not (at all)…

I am sorry I can not post the whole source code of the application as this frame work is used to develop various programs for my company… But of course, I am always ready to help with “how to do it” and even post some snippet…

And Bob, if you are interested in trying this frame work (the frame work alone does nothing except display some objects you can play with !), please tell me and I’ll send you an executable…

Sorry for this huge post but I thought some people could be interested in the problems I solved in the past 2 weeks (I know spherical billboard is mentioned at least once a month here !).

Best regards.

Eric