www.jpct.net
jPCT  a 3d engine for Java => Support => Topic started by: gonso on December 21, 2008, 08:25:05 pm

Hello,
After using the code:
obj.rotateY((float) Math.PI/2f);
How could I get the angle to Y axis back? I mean, is there something simillar to
float beta=obj.getYangle();
?
Obviously getting beta=PI/2 as the result in this case assuming that originally beta was 0.
Thanks.

It should be possible to write a method that returns SOME rotations that could result in the Object's rotation matrix (not necessarily the same rotations that the object underwent, but some that are equivalent). I am not very good at trigonometry myself, so I will leave the question open to the more intelligent programmers on this forum. You might find this article (http://en.wikipedia.org/wiki/Rotation_representation_(mathematics)) helpful, specifically the section on "Conversion formulae between representations", "DCM to Euler angles".

I've been giving this problem some more thought, and I think I have thought of a way to create the getXAngle(), getYAngle(), and getZAngle() methods you are looking for. It is kind of just a theory at this point, I haven't had a chance to actually test it in a program.
Basically, you would project one of the object's other two axis' onto a plane parallel to the world counterpart of that second axis. Then you would calculate normal vectors for that axis and the corresponding world axis on that plane and use the law of cosines to determine the angle between them. Coordinate signs would determine if the angle should be positive or negative.
I am sure that sounds like jibberish, so I drew a diagram that might help visualize what I am talking about:
(http://www.paulscode.com/images/AxisProjection.gif)
So here is an (untested) example for how a getYAngle() method might look using this idea:
public float getYAngle( Object3D object )
{
// The Object's Zaxis:
SimpleVector directionI = new SimpleVector( object.getZAxis() );
// Project onto the x/z plane:
directionI.y = 0;
// make sure it is length=1:
directionI.normalize();
// The World's Zaxis:
SimpleVector directionD = new SimpleVector( 0, 0, 1 );
// Length of the triangle's third side:
float distC = directionD.calcSub( directionI ).length();
// Yangle (unsigned):
float angle = (float) Math.acos( (2.0f  (distC * distC)) / 2.0f );
// Sign the angle (TODO  make sure this isn't backwards):
if( directionI.x > 0 )
angle = angle;
return angle;
}
The methods for getXAngle() and getZAngle() would be almost identical, except projecting each onto one of the planes perpendicular (i.e. in getYAngle() we were looking from overhead projecting Zaxis' onto the XZ plane, so in getXAngle() we would look from the left projecting Yaxis' onto the YZ plane, and for getZAngle() we would look from the back projecting Xaxis' onto the XY plane).
Oh, and I would like to point out that these methods would return rotations around the absolute world axis' ( (1, 0, 0), (0, 1, 0), and (0, 0, 1) ), not the relative object's axis (which would change as you rotated the object).

You can get some angles like mentioned here: http://www.jpct.net/forum2/index.php/topic,1191.0.html (http://www.jpct.net/forum2/index.php/topic,1191.0.html)
However, they are not necessarily the same that were used to create the matrix. Personally, i suggest to sick with matrices whenever possible and don't convert matrices back to angles and vice versa with no need, because you may run into gimbal lock problems.