Used in 3D applications, Euler angles 'in general' often become an endless source of surprise, confusion and pain. In contrast, aeronautic coordinates use well defined conventions
Please assume a vehicle's nose (think of a plane) is pointing towards Z positive, and its right wing is lying along the X axis. Many game developers find this orientation intuitive.
Aeronautic coordinates, consist in pitch, yaw and roll, also known as atttidue, heading and bank.
In some litterature you will find the term 'attitude' used to refer aeronautic coordinates altogether.
Unity3D implementation => [source]
- Pitch/Attitude - an angle indicating whether a vehicle is flying upwards or downwards.
- Yaw/Heading - an angle indicating a vehicle's general direction/course. In the real world, cardinal points (north, south, east, west) are often used to refer a vehicle's heading but this is unpractical when dealing with computers.
- Roll/bank - an angle indicating whether a vehicle is tilted or not. For example, a plane is 'tilted' when their wings do not lie in the horizontal plane.
CalculationsWhile there are many ways to extract aeronautic coordinates from a transform, and quite possibly several correct ways to do so, I will suggest an approach which I hope you will find safe and intuitive.
I assume that you have access to the forward, right and up vectors associated with your transform.
Then you can use the following recipes:
Return -asin( forward.y )
Let F be the ground projection of the forward vector.
Let R be the ground projection of the right vector
If u is small/degenerate:
Let α be the angle between R and the right vector (1,0,0)
Return R.z<0 ? α : -α
Let α be the angle between u and the forward vector (0,0,1)
Return F.x>0 ? α :-α
Important: Your forward, right and up vectors must be normalized.
Occasionally APIs return components (slightly) without the [ -1, 1 ] inclusive range. clamp right.y, forward.y to make sure that this doesn't happen, otherwise asin would return incorrect values.
With some implementations, the heading is undefined when a vehicle is pointing straight up. This satisfies the (flawed) intuition that a vehicle pointing upwards isn't going north, east, west or south. It is a flawed intuition because, even when a plane is flying straight up, you can infer its heading from the position of its wings. The suggested recipe and linked implementation leverage this idea to avoid errors.