I want to find the angle for the rotation of an object around a certain axis

Hi, I'm trying to write a method to an angle of a model of a plane. This model can be in any orientation, rotation, speed etc but I need to be able to return an angle for its roll, relative to the model. I've tried getLocalRotation but this returns a quaternion and i've been watching the values in it and none of them seem to just represent the roll angle. Could anyone suggest how this can be done please?



Cheers,

Adam

I don't know if this will help, but the entries in a quaternion mean something geometrical:



w is the cosine of half the angle used to rotate

(x, y, z) is the axis of rotation.



Since you have a very general case, you might want to describe exactly what is it that you want to measure (which angle or a projection of which angle in which plane, etc).

Thanks for the speedy reply,



Not sure what you mean about the geometrical stuff - doesn't sound like I can get a certain angle out on demand.



I have a model of an aeroplane [thats what I meant by plane, maybe it was an unfortunate choice of word :D] and I want to find the "roll" angle. Is what what you mean?

I think that you can achieve what you try to do if you simply get the LocalRotation, which is a quaternion, and then multiply it for another quaternion which is the rotation you try to apply.



To build the second quaternion, you can use some of the helper methods of the Quaternion class: fromAngleAxis, fromAngles… have a look at those.



So for example, to roll (i.e. using ailerons), if your airplane model is orientated facing the positive Z axis, you would use:


Quaternion rotation = new Quaternion();
rotation.fromAngleAxis (yourangle_radians, Vector3f.UNIT_Z);
airplane.getLocalRotation().multiplyLocal(rotation);



As you see, Quaternions represent a rotation itself, not the "orientation", this is useful to manage rotations. For example, multiplying your previous LocalRotation by the same rotation quaternion will produce a continuous rotation effect.

Hope it helps.

Hi,



You're actually describing a piece of functionality I've already implemented - I'm trying to find the roll angle, not set it :slight_smile: as in, get the game to give me a value between 0 and 2pi. Is this possible?


spatial.getLocalRotation().toAngles( null ) returns the three euler angles in an array of floats.



Is this along the lines of what you need?





w is the cosine of half the angle used to rotate
(x, y, z) is the axis of rotation.

Without i is a quaternion really just the axis and half angle?  I thought it was a representation of a rotation in 4 dimensions.  But I am not a math wiz by any means.

Well, almost, the w component is really the cosine of half the angle, the (x,y,z) components denote the axis of rotation (counter-clock-wise).

I am still trying to understand how that makes it so different from AxisAngle that it can: avoid gimbal lock, be accumulated into one quaternion and can be interpolated between two quaternions.  Is it just a magical alignment of the numbers??



I know this is off topic, but I like to learn.

Actually I would say that it is magic, but not magical alignment of numbers… The thing is that unity Quaternions (which you can think of as 4 entry vectors) form what is called a non-commutative group. That means you can linearly interpolate (linear in this case, over the 4-dimensional sphere) between them to have a smooth transition from one (representing one orientation) to another. Also allows you to understand geometrically the meaning which is the coolest part. Is very much like unity complex numbers which denote 2D rotations, and magically you can know the angle, assuming you know your complex entries (x+iy).



Hope it helps.

Aha!    .toAngles( null )    - exactly what I wanted! thanks :slight_smile: don't know why I didn't see that before. I've converted the radians given to degrees and in a situation where the plane is flying pretty straight with not much pitch, rolling the plane makes the angle goes from 0 [horizontal] through to 90 degrees [vertical] BUT this range seems to decrease a lot when the plane is climbing or falling significantly. This does not matter too much but I was wondering why it does this?



Thanks again

Glad I could help adam.dullenty :smiley:


rolling the plane makes the angle goes from 0 [horizontal] through to 90 degrees [vertical]

Assumptions: this is an instantaneous change and it's unwanted.
Are you using quaternions to hold your rotations?  Or AxisAngle?
(hint: You should be using quaternions)
This is just a possibility, I haven't experienced that exact problem before...



Actually I would say that it is magic, but not magical alignment of numbers... The thing is that unity Quaternions (which you can think of as 4 entry vectors) form what is called a non-commutative group. That means you can linearly interpolate (linear in this case, over the 4-dimensional sphere) between them to have a smooth transition from one (representing one orientation) to another. Also allows you to understand geometrically the meaning which is the coolest part. Is very much like unity complex numbers which denote 2D rotations, and magically you can know the angle, assuming you know your complex entries (x+iy).


I am more confused now than before, but thats okay. I understand how they work which is enough for now...
basixs said:


Assumptions: this is an instantaneous change and it's unwanted.
Are you using quaternions to hold your rotations?  Or AxisAngle?


Actually, no, the roll angle reported moves smoothly from 0 right through to 90 when the plane is flying with no pitch. This is the desired function. However, as the pitch increases, the maximum possible reported roll angle decreases.

I have converted the angle reported into degrees so they are easier to work with. I have also squared/square rooted to remove the negative, as this makes it easier to have a condition for horizontal flying (angle<10) and vertical flying (angle>=80). This is what happens when the plane is flying with zero pitch.




      ^^
WW
    = 0 degrees  horizontal

 

    |
    |
    |
    E>        = 90 degrees  vertical [full roll right]
    E>
    |
    |
    |


MM
    = 0 degrees    horizontal [upside down]
      VV


      |
      |
      |
    <3          = 90 degrees      vertical [full roll left]
    <3
      |
      |
      |

Say the plane is flying straight with no roll or pitch. roll angle is reported as 0, which is good. I roll hard right and it reports 90 degrees roll, which is correct. however, if the plane is flying straight but with a slight upwards pitch, the roll angle reported by plane.getLocalRotation().toAngles( null )  for hard right will decrease to ~60. generally the maximum roll angle reported will decrease with increased pitch on the plane. I was just curious as to why this happens, it isn't a major worry but in my eyes the roll angle should always go up to 90 degrees no matter what the angle of its pitch is.

This happens because toAngles reports them in order, that is, first you apply pitch (X-axis), then yaw (Y-axis) and finally roll (Z-axis). That is the problem with euler angles, they are very dependent on the ordering… If you want to measure roll only, which is the last rotation, then you might have to define precisely what you mean be a 90deg to the right roll. And it does not suffice to say that it is when the plane 'looks' vertical.

Maybe what you are looking for should not be obtained from your plane orientation only.



Think of this as if your wings are or ar not pointing to the ground. In your second picture (full roll right) your airplane right wing is pointing perpendicular to the ground.



Now, if you are heading slightly upwards or downwards, your right wing doesn't point completely perpendicular to the ground. Moreover, if you are falling directly towards the ground, I'd say the "roll" term has no sense in the way you were defining it.



If you try to implement an "artificial horizon" instrument for your airplane, you would incur in the same issue. I find this quite difficult to explain  ://.



If you want to know if you are heading upwards (vertical), you could maybe find the angle between your "forward" vector and the ground plane normal. That way you will have the real amount of degrees between your plane nose and the "perfect" vertical, no matter the roll.



I am just guessing. Hope it helps though.

I have also squared/square rooted to remove the negative

That seems a little inefficient, is there a way to multiply by -1?
jjmontes said:

Think of this as if your wings are or ar not pointing to the ground. In your second picture (full roll right) your airplane right wing is pointing perpendicular to the ground.

Now, if you are heading slightly upwards or downwards, your right wing doesn't point completely perpendicular to the ground. Moreover, if you are falling directly towards the ground, I'd say the "roll" term has no sense in the way you were defining it.


Ahh, right. That makes a lot more sense now - thanks for explaining it, I think I've understood what you mean now.

basixs said:

I have also squared/square rooted to remove the negative

That seems a little inefficient, is there a way to multiply by -1?


I realised later that Math.abs() would do it for me :)

Edit: Nevermind…