mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-23 00:58:48 +00:00
Add Quaternion.ToAxisAngle and Quaternion.ToVector3
This commit is contained in:
parent
b60fdc495b
commit
9d6dbaaa23
@ -31,6 +31,8 @@
|
||||
- X10D: Added `PointF.ToSizeF()`
|
||||
- X10D: Added `PointF.ToVector2()` for .NET < 6
|
||||
- X10D: Added `PopCount()` for built-in integer types
|
||||
- X10D: Added `Quaternion.ToAxisAngle(out float, out float)`
|
||||
- X10D: Added `Quaternion.ToVector3()`
|
||||
- X10D: Added `ReadOnlySpan<char>.CountSubstring(char)`
|
||||
- X10D: Added `ReadOnlySpan<char>.CountSubstring(ReadOnlySpan<char>[, StringComparison])`
|
||||
- X10D: Added `ReadOnlySpan<T>.Split(T)`
|
||||
|
21
X10D.Tests/src/Numerics/QuaternionTests.cs
Normal file
21
X10D.Tests/src/Numerics/QuaternionTests.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Numerics;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using X10D.Numerics;
|
||||
|
||||
namespace X10D.Tests.Numerics;
|
||||
|
||||
[TestClass]
|
||||
public class QuaternionTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void ToAxisAngle_ShouldGiveAngle180VectorZero_GivenQuaternion()
|
||||
{
|
||||
Vector3 axis = Vector3.UnitY;
|
||||
const float angle = MathF.PI;
|
||||
var quaternion = Quaternion.CreateFromAxisAngle(axis, angle);
|
||||
|
||||
(Vector3 Axis, float Angle) axisAngle = quaternion.ToAxisAngle();
|
||||
Assert.AreEqual(axis, axisAngle.Axis);
|
||||
Assert.AreEqual(angle, axisAngle.Angle);
|
||||
}
|
||||
}
|
@ -38,4 +38,35 @@ public static class QuaternionExtensions
|
||||
(xz - wy) * px + (yz + wx) * py + (1.0f - (xx + yy)) * pz
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this quaternion to an axis/angle pair.
|
||||
/// </summary>
|
||||
/// <param name="value">The quaternion to convert.</param>
|
||||
/// <returns>A tuple containing the converted axis, and the angle in radians.</returns>
|
||||
public static (Vector3 Axis, float Angle) ToAxisAngle(this in Quaternion value)
|
||||
{
|
||||
float angle = 2.0f * MathF.Acos(value.W);
|
||||
Vector3 axis = Vector3.Normalize(new Vector3(value.X, value.Y, value.Z));
|
||||
return (axis, angle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this quaternion to a <see cref="Vector3" /> containing an Euler representation of the rotation.
|
||||
/// </summary>
|
||||
/// <param name="value">The quaternion to convert.</param>
|
||||
/// <returns>The Euler representation of <paramref name="value" />, in radians.</returns>
|
||||
public static Vector3 ToVector3(this in Quaternion value)
|
||||
{
|
||||
Quaternion normalized = Quaternion.Normalize(value);
|
||||
float qx = normalized.X;
|
||||
float qy = normalized.Y;
|
||||
float qz = normalized.Z;
|
||||
float qw = normalized.W;
|
||||
|
||||
float x = MathF.Atan2(2 * (qx * qw - qy * qz), 1 - 2 * (qx * qx + qz * qz));
|
||||
float y = MathF.Asin(2 * (qx * qz + qy * qw));
|
||||
float z = MathF.Atan2(2 * (qz * qw - qx * qy), 1 - 2 * (qy * qy + qz * qz));
|
||||
return new Vector3(x, y, z);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user