Provide fix for converting euler angles to quaternion

Fixed API documentation and changed convertion from euler angles to quaterion:

Rotation will applied in following order: 1. xAxis, 2. yAxis, 3. zAxis.
Right hand rule is used here. Rotation is interpreted counter clock wise, in viewing direction of positive axis. Still need to double check that with unit tests.
This commit is contained in:
Unknown 2018-01-02 17:53:04 +01:00
parent f0e5754abc
commit fca36b19b0

View file

@ -66,34 +66,36 @@ namespace OpenTK
{ } { }
/// <summary> /// <summary>
/// Construct a new Quaternion from given Euler angles /// Construct a new Quaternion from given Euler angles. The rotations will get applied in following order:
/// 1. Around X, 2. Around Y, 3. Around Z
/// </summary> /// </summary>
/// <param name="pitch">The pitch (attitude), rotation around X axis</param> /// <param name="rotationX">Counterclockwise rotation around X axis in radian</param>
/// <param name="yaw">The yaw (heading), rotation around Y axis</param> /// <param name="rotationY">Counterclockwise rotation around Y axis in radian</param>
/// <param name="roll">The roll (bank), rotation around Z axis</param> /// <param name="rotationZ">Counterclockwise rotation around Z axis in radian</param>
public Quaternion(float pitch, float yaw, float roll) public Quaternion(float rotationX, float rotationY, float rotationZ)
{ {
yaw *= 0.5f; rotationX *= 0.5f;
pitch *= 0.5f; rotationY *= 0.5f;
roll *= 0.5f; rotationZ *= 0.5f;
float c1 = (float)Math.Cos(yaw); float c1 = (float)Math.Cos(rotationX);
float c2 = (float)Math.Cos(pitch); float c2 = (float)Math.Cos(rotationY);
float c3 = (float)Math.Cos(roll); float c3 = (float)Math.Cos(rotationZ);
float s1 = (float)Math.Sin(yaw); float s1 = (float)Math.Sin(rotationX);
float s2 = (float)Math.Sin(pitch); float s2 = (float)Math.Sin(rotationY);
float s3 = (float)Math.Sin(roll); float s3 = (float)Math.Sin(rotationZ);
W = c1 * c2 * c3 - s1 * s2 * s3; W = c1 * c2 * c3 - s1 * s2 * s3;
Xyz.X = s1 * s2 * c3 + c1 * c2 * s3; Xyz.X = s1 * c2 * c3 + c1 * s2 * s3;
Xyz.Y = s1 * c2 * c3 + c1 * s2 * s3; Xyz.Y = c1 * s2 * c3 - s1 * c2 * s3;
Xyz.Z = c1 * s2 * c3 - s1 * c2 * s3; Xyz.Z = c1 * c2 * s3 + s1 * s2 * c3;
} }
/// <summary> /// <summary>
/// Construct a new Quaternion from given Euler angles /// Construct a new Quaternion from given Euler angles. The rotations will get applied in following order:
/// 1. Around X, 2. Around Y, 3. Around Z
/// </summary> /// </summary>
/// <param name="eulerAngles">The euler angles as a Vector3</param> /// <param name="eulerAngles">The counterclockwise euler angles as a Vector3</param>
public Quaternion(Vector3 eulerAngles) public Quaternion(Vector3 eulerAngles)
: this(eulerAngles.X, eulerAngles.Y, eulerAngles.Z) : this(eulerAngles.X, eulerAngles.Y, eulerAngles.Z)
{ } { }
@ -431,10 +433,12 @@ namespace OpenTK
/// <summary> /// <summary>
/// Builds a Quaternion from the given euler angles /// Builds a Quaternion from the given euler angles
/// The rotations will get applied in following order:
/// 1. pitch, 2. yaw, 3. roll
/// </summary> /// </summary>
/// <param name="pitch">The pitch (attitude), rotation around X axis</param> /// <param name="pitch">The pitch (attitude), counterclockwise rotation around X axis</param>
/// <param name="yaw">The yaw (heading), rotation around Y axis</param> /// <param name="yaw">The yaw (heading), counterclockwise rotation around Y axis</param>
/// <param name="roll">The roll (bank), rotation around Z axis</param> /// <param name="roll">The roll (bank), counterclockwise rotation around Z axis</param>
/// <returns></returns> /// <returns></returns>
public static Quaternion FromEulerAngles(float pitch, float yaw, float roll) public static Quaternion FromEulerAngles(float pitch, float yaw, float roll)
{ {
@ -443,8 +447,10 @@ namespace OpenTK
/// <summary> /// <summary>
/// Builds a Quaternion from the given euler angles /// Builds a Quaternion from the given euler angles
/// The rotations will get applied in following order:
/// 1. Around X, 2. Around Y, 3. Around Z
/// </summary> /// </summary>
/// <param name="eulerAngles">The euler angles as a vector</param> /// <param name="eulerAngles">The counterclockwise euler angles as a vector</param>
/// <returns>The equivalent Quaternion</returns> /// <returns>The equivalent Quaternion</returns>
public static Quaternion FromEulerAngles(Vector3 eulerAngles) public static Quaternion FromEulerAngles(Vector3 eulerAngles)
{ {
@ -452,23 +458,26 @@ namespace OpenTK
} }
/// <summary> /// <summary>
/// Builds a Quaternion from the given euler angles /// Builds a Quaternion from the given euler angles in radians.
/// The rotations will get applied in following order:
/// 1. Around X, 2. Around Y, 3. Around Z
/// </summary> /// </summary>
/// <param name="eulerAngles">The euler angles a vector</param> /// <param name="eulerAngles">The counterclockwise euler angles a vector</param>
/// <param name="result">The equivalent Quaternion</param> /// <param name="result">The equivalent Quaternion</param>
public static void FromEulerAngles(ref Vector3 eulerAngles, out Quaternion result) public static void FromEulerAngles(ref Vector3 eulerAngles, out Quaternion result)
{ {
float c1 = (float)Math.Cos(eulerAngles.Y * 0.5f);
float c2 = (float)Math.Cos(eulerAngles.X * 0.5f); float c1 = (float)Math.Cos(eulerAngles.X * 0.5f);
float c2 = (float)Math.Cos(eulerAngles.Y * 0.5f);
float c3 = (float)Math.Cos(eulerAngles.Z * 0.5f); float c3 = (float)Math.Cos(eulerAngles.Z * 0.5f);
float s1 = (float)Math.Sin(eulerAngles.Y * 0.5f); float s1 = (float)Math.Sin(eulerAngles.X * 0.5f);
float s2 = (float)Math.Sin(eulerAngles.X * 0.5f); float s2 = (float)Math.Sin(eulerAngles.Y * 0.5f);
float s3 = (float)Math.Sin(eulerAngles.Z * 0.5f); float s3 = (float)Math.Sin(eulerAngles.Z * 0.5f);
result.W = c1 * c2 * c3 - s1 * s2 * s3; result.W = c1 * c2 * c3 - s1 * s2 * s3;
result.Xyz.X = s1 * s2 * c3 + c1 * c2 * s3; result.Xyz.X = s1 * c2 * c3 + c1 * s2 * s3;
result.Xyz.Y = s1 * c2 * c3 + c1 * s2 * s3; result.Xyz.Y = c1 * s2 * c3 - s1 * c2 * s3;
result.Xyz.Z = c1 * s2 * c3 - s1 * c2 * s3; result.Xyz.Z = c1 * c2 * s3 + s1 * s2 * c3;
} }
/// <summary> /// <summary>