Getting Angles back

Started by gonso, December 21, 2008, 08:25:05 PM

Previous topic - Next topic

gonso

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.

paulscode

#1
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 helpful, specifically the section on "Conversion formulae between representations", "DCM to Euler angles".

paulscode

#2
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:



So here is an (untested) example for how a getYAngle() method might look using this idea:

public float getYAngle( Object3D object )
{
    // The Object's Z-axis:
    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 Z-axis:
    SimpleVector directionD = new SimpleVector( 0, 0, 1 );

    // Length of the triangle's third side:
    float distC = directionD.calcSub( directionI ).length();

    // Y-angle (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 Z-axis' onto the XZ plane, so in getXAngle() we would look from the left projecting Y-axis' onto the YZ plane, and for getZAngle() we would look from the back projecting X-axis' 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).

EgonOlsen

You can get some angles like mentioned here: 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.