diff --git a/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj b/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj
index 47a3bf9c341a..16e8924b81e4 100644
--- a/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj
+++ b/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj
@@ -66,12 +66,21 @@
System\MathF.netstandard.cs
+
+
+
+
+
+
+
+
+
+
-
diff --git a/src/System.Numerics.Vectors/src/System/Numerics/Quaternion.netcoreapp.cs b/src/System.Numerics.Vectors/src/System/Numerics/Quaternion.netcoreapp.cs
new file mode 100644
index 000000000000..ca4213945fee
--- /dev/null
+++ b/src/System.Numerics.Vectors/src/System/Numerics/Quaternion.netcoreapp.cs
@@ -0,0 +1,669 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Globalization;
+using Internal.Runtime.CompilerServices;
+
+namespace System.Numerics
+{
+ ///
+ /// A structure encapsulating a four-dimensional vector (x,y,z,w),
+ /// which is used to efficiently rotate an object about the (x,y,z) vector by the angle theta, where w = cos(theta/2).
+ ///
+ public struct Quaternion : IEquatable
+ {
+ ///
+ /// Specifies the X-value of the vector component of the Quaternion.
+ ///
+ public float X;
+ ///
+ /// Specifies the Y-value of the vector component of the Quaternion.
+ ///
+ public float Y;
+ ///
+ /// Specifies the Z-value of the vector component of the Quaternion.
+ ///
+ public float Z;
+ ///
+ /// Specifies the rotation component of the Quaternion.
+ ///
+ public float W;
+
+ ///
+ /// Returns a Quaternion representing no rotation.
+ ///
+ public static Quaternion Identity
+ {
+ get { return new Quaternion(0, 0, 0, 1); }
+ }
+
+ ///
+ /// Returns whether the Quaternion is the identity Quaternion.
+ ///
+ public bool IsIdentity
+ {
+ get { return X == 0f && Y == 0f && Z == 0f && W == 1f; }
+ }
+
+ ///
+ /// Constructs a Quaternion from the given components.
+ ///
+ /// The X component of the Quaternion.
+ /// The Y component of the Quaternion.
+ /// The Z component of the Quaternion.
+ /// The W component of the Quaternion.
+ public Quaternion(float x, float y, float z, float w)
+ {
+ this.X = x;
+ this.Y = y;
+ this.Z = z;
+ this.W = w;
+ }
+
+ ///
+ /// Constructs a Quaternion from the given vector and rotation parts.
+ ///
+ /// The vector part of the Quaternion.
+ /// The rotation part of the Quaternion.
+ public Quaternion(Vector3 vectorPart, float scalarPart)
+ {
+ X = vectorPart.X;
+ Y = vectorPart.Y;
+ Z = vectorPart.Z;
+ W = scalarPart;
+ }
+
+ ///
+ /// Calculates the length of the Quaternion.
+ ///
+ /// The computed length of the Quaternion.
+ public float Length()
+ {
+ Vector4 q = Unsafe.As(ref this);
+ return q.Length();
+ }
+
+ ///
+ /// Calculates the length squared of the Quaternion. This operation is cheaper than Length().
+ ///
+ /// The length squared of the Quaternion.
+ public float LengthSquared()
+ {
+ Vector4 q = Unsafe.As(ref this);
+ return q.LengthSquared();
+ }
+
+ ///
+ /// Divides each component of the Quaternion by the length of the Quaternion.
+ ///
+ /// The source Quaternion.
+ /// The normalized Quaternion.
+ public static Quaternion Normalize(Quaternion value)
+ {
+ Vector4 q = Unsafe.As(ref value);
+ q = Vector4.Normalize(q);
+ return Unsafe.As(ref q);
+ }
+
+ ///
+ /// Creates the conjugate of a specified Quaternion.
+ ///
+ /// The Quaternion of which to return the conjugate.
+ /// A new Quaternion that is the conjugate of the specified one.
+ public static Quaternion Conjugate(Quaternion value)
+ {
+ Vector4 q = -Unsafe.As(ref value);
+ q.W = -q.W;
+ return Unsafe.As(ref q);
+ }
+
+ ///
+ /// Returns the inverse of a Quaternion.
+ ///
+ /// The source Quaternion.
+ /// The inverted Quaternion.
+ public static Quaternion Inverse(Quaternion value)
+ {
+ // -1 ( a -v )
+ // q = ( ------------- ------------- )
+ // ( a^2 + |v|^2 , a^2 + |v|^2 )
+
+ Vector4 q = Unsafe.As(ref value);
+
+ float ls = Vector4.Dot(q, q);
+ float invNorm = -1.0f / ls;
+
+ q *= invNorm;
+ q.W = -q.W;
+
+ return Unsafe.As(ref q);
+ }
+
+ ///
+ /// Creates a Quaternion from a normalized vector axis and an angle to rotate about the vector.
+ ///
+ /// The unit vector to rotate around.
+ /// This vector must be normalized before calling this function or the resulting Quaternion will be incorrect.
+ /// The angle, in radians, to rotate around the vector.
+ /// The created Quaternion.
+ public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)
+ {
+ float halfAngle = angle * 0.5f;
+ float s = MathF.Sin(halfAngle);
+ float c = MathF.Cos(halfAngle);
+
+ Vector4 q = new Vector4(axis, 0) * s;
+
+ q.W = c;
+
+ return Unsafe.As(ref q);
+ }
+
+ ///
+ /// Creates a new Quaternion from the given yaw, pitch, and roll, in radians.
+ ///
+ /// The yaw angle, in radians, around the Y-axis.
+ /// The pitch angle, in radians, around the X-axis.
+ /// The roll angle, in radians, around the Z-axis.
+ ///
+ public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
+ {
+ // Roll first, about axis the object is facing, then
+ // pitch upward, then yaw to face into the new heading
+ float sr, cr, sp, cp, sy, cy;
+
+ float halfRoll = roll * 0.5f;
+ sr = MathF.Sin(halfRoll);
+ cr = MathF.Cos(halfRoll);
+
+ float halfPitch = pitch * 0.5f;
+ sp = MathF.Sin(halfPitch);
+ cp = MathF.Cos(halfPitch);
+
+ float halfYaw = yaw * 0.5f;
+ sy = MathF.Sin(halfYaw);
+ cy = MathF.Cos(halfYaw);
+
+ Vector4 result =
+ new Vector4(
+ cy * sp * cr,
+ sy * cp * cr,
+ cy * cp * sr,
+ cy * cp * cr)
+ + new Vector4(
+ sy * cp * sr,
+ -cy * sp * sr,
+ -sy * sp * cr,
+ sy * sp * sr);
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Creates a Quaternion from the given rotation matrix.
+ ///
+ /// The rotation matrix.
+ /// The created Quaternion.
+ public static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix)
+ {
+ float trace = matrix.M11 + matrix.M22 + matrix.M33;
+
+ Quaternion q = new Quaternion();
+
+ if (trace > 0.0f)
+ {
+ float s = MathF.Sqrt(trace + 1.0f);
+ q.W = s * 0.5f;
+ s = 0.5f / s;
+ q.X = (matrix.M23 - matrix.M32) * s;
+ q.Y = (matrix.M31 - matrix.M13) * s;
+ q.Z = (matrix.M12 - matrix.M21) * s;
+ }
+ else
+ {
+ if (matrix.M11 >= matrix.M22 && matrix.M11 >= matrix.M33)
+ {
+ float s = MathF.Sqrt(1.0f + matrix.M11 - matrix.M22 - matrix.M33);
+ float invS = 0.5f / s;
+ q.X = 0.5f * s;
+ q.Y = (matrix.M12 + matrix.M21) * invS;
+ q.Z = (matrix.M13 + matrix.M31) * invS;
+ q.W = (matrix.M23 - matrix.M32) * invS;
+ }
+ else if (matrix.M22 > matrix.M33)
+ {
+ float s = MathF.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33);
+ float invS = 0.5f / s;
+ q.X = (matrix.M21 + matrix.M12) * invS;
+ q.Y = 0.5f * s;
+ q.Z = (matrix.M32 + matrix.M23) * invS;
+ q.W = (matrix.M31 - matrix.M13) * invS;
+ }
+ else
+ {
+ float s = MathF.Sqrt(1.0f + matrix.M33 - matrix.M11 - matrix.M22);
+ float invS = 0.5f / s;
+ q.X = (matrix.M31 + matrix.M13) * invS;
+ q.Y = (matrix.M32 + matrix.M23) * invS;
+ q.Z = 0.5f * s;
+ q.W = (matrix.M12 - matrix.M21) * invS;
+ }
+ }
+
+ return q;
+ }
+
+ ///
+ /// Calculates the dot product of two Quaternions.
+ ///
+ /// The first source Quaternion.
+ /// The second source Quaternion.
+ /// The dot product of the Quaternions.
+ public static float Dot(Quaternion quaternion1, Quaternion quaternion2)
+ {
+ return Vector4.Dot(
+ Unsafe.As(ref quaternion1),
+ Unsafe.As(ref quaternion2));
+ }
+
+ ///
+ /// Interpolates between two quaternions, using spherical linear interpolation.
+ ///
+ /// The first source Quaternion.
+ /// The second source Quaternion.
+ /// The relative weight of the second source Quaternion in the interpolation.
+ /// The interpolated Quaternion.
+ public static Quaternion Slerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
+ {
+ const float epsilon = 1e-6f;
+
+ float t = amount;
+
+ Vector4 q1 = Unsafe.As(ref quaternion1);
+ Vector4 q2 = Unsafe.As(ref quaternion2);
+
+ float cosOmega = Vector4.Dot(q1, q2);
+
+ bool flip = false;
+
+ if (cosOmega < 0.0f)
+ {
+ flip = true;
+ cosOmega = -cosOmega;
+ }
+
+ float s1, s2;
+
+ if (cosOmega > (1.0f - epsilon))
+ {
+ // Too close, do straight linear interpolation.
+ s1 = 1.0f - t;
+ s2 = (flip) ? -t : t;
+ }
+ else
+ {
+ float omega = MathF.Acos(cosOmega);
+ float invSinOmega = 1 / MathF.Sin(omega);
+
+ s1 = MathF.Sin((1.0f - t) * omega) * invSinOmega;
+ s2 = (flip)
+ ? -MathF.Sin(t * omega) * invSinOmega
+ : MathF.Sin(t * omega) * invSinOmega;
+ }
+
+ Vector4 result = q1 * s1 + q2 * s2;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Linearly interpolates between two quaternions.
+ ///
+ /// The first source Quaternion.
+ /// The second source Quaternion.
+ /// The relative weight of the second source Quaternion in the interpolation.
+ /// The interpolated Quaternion.
+ public static Quaternion Lerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
+ {
+ float t = amount;
+ float t1 = 1.0f - t;
+
+ Vector4 q1 = Unsafe.As(ref quaternion1);
+ Vector4 q2 = Unsafe.As(ref quaternion2);
+
+ float dot = Vector4.Dot(q1, q2);
+
+ q1 *= t1;
+ if (dot >= 0.0f)
+ {
+ q2 *= t;
+ }
+ else
+ {
+ q2 *= -t;
+ }
+
+ Vector4 result = Vector4.Normalize(q1 + q2);
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Concatenates two Quaternions; the result represents the value1 rotation followed by the value2 rotation.
+ ///
+ /// The first Quaternion rotation in the series.
+ /// The second Quaternion rotation in the series.
+ /// A new Quaternion representing the concatenation of the value1 rotation followed by the value2 rotation.
+ public static Quaternion Concatenate(Quaternion value1, Quaternion value2)
+ {
+ float q1w = value1.W;
+ float q2w = value2.W;
+
+ Vector3 vec1 = Unsafe.As(ref value1);
+ Vector3 vec2 = Unsafe.As(ref value2);
+
+ float dot = Vector3.Dot(vec1, vec2);
+
+ Vector3 vectorPart = Vector3.Cross(vec2, vec1) + vec1 * q2w + vec2 * q1w;
+ float scalarPart = q1w * q2w - dot;
+
+ return new Quaternion(vectorPart, scalarPart);
+ }
+
+ ///
+ /// Flips the sign of each component of the quaternion.
+ ///
+ /// The source Quaternion.
+ /// The negated Quaternion.
+ public static Quaternion Negate(Quaternion value)
+ {
+ Vector4 q = Unsafe.As(ref value);
+ Vector4 result = -q;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Adds two Quaternions element-by-element.
+ ///
+ /// The first source Quaternion.
+ /// The second source Quaternion.
+ /// The result of adding the Quaternions.
+ public static Quaternion Add(Quaternion value1, Quaternion value2)
+ {
+ Vector4 q1 = Unsafe.As(ref value1);
+ Vector4 q2 = Unsafe.As(ref value2);
+
+ Vector4 result = q1 + q2;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Subtracts one Quaternion from another.
+ ///
+ /// The first source Quaternion.
+ /// The second Quaternion, to be subtracted from the first.
+ /// The result of the subtraction.
+ public static Quaternion Subtract(Quaternion value1, Quaternion value2)
+ {
+ Vector4 q1 = Unsafe.As(ref value1);
+ Vector4 q2 = Unsafe.As(ref value2);
+
+ Vector4 result = q1 - q2;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Multiplies two Quaternions together.
+ ///
+ /// The Quaternion on the left side of the multiplication.
+ /// The Quaternion on the right side of the multiplication.
+ /// The result of the multiplication.
+ public static Quaternion Multiply(Quaternion value1, Quaternion value2)
+ {
+ float q1w = value1.W;
+ float q2w = value2.W;
+
+ Vector3 vec1 = Unsafe.As(ref value1);
+ Vector3 vec2 = Unsafe.As(ref value2);
+
+ float dot = Vector3.Dot(vec1, vec2);
+
+ Vector3 vectorPart = Vector3.Cross(vec1, vec2) + vec1 * q2w + vec2 * q1w;
+ float scalarPart = q1w * q2w - dot;
+
+ return new Quaternion(vectorPart, scalarPart);
+ }
+
+ ///
+ /// Multiplies a Quaternion by a scalar value.
+ ///
+ /// The source Quaternion.
+ /// The scalar value.
+ /// The result of the multiplication.
+ public static Quaternion Multiply(Quaternion value1, float value2)
+ {
+ Vector4 q1 = Unsafe.As(ref value1);
+
+ Vector4 result = q1 * value2;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Divides a Quaternion by another Quaternion.
+ ///
+ /// The source Quaternion.
+ /// The divisor.
+ /// The result of the division.
+ public static Quaternion Divide(Quaternion value1, Quaternion value2)
+ {
+ Vector4 q2 = Unsafe.As(ref value2);
+
+ // Inverse part.
+ float ls = Vector4.Dot(q2, q2);
+ float invNorm = -1.0f / ls;
+ Vector4 q = q2 * invNorm;
+ float q2w = -q.W;
+
+ // Multiply part.
+ float q1w = value1.W;
+ Vector3 vec1 = Unsafe.As(ref value1);
+ Vector3 vec2 = Unsafe.As(ref q);
+
+ float dot = Vector3.Dot(vec1, vec2);
+
+ Vector3 vectorPart = Vector3.Cross(vec1, vec2) + vec1 * q2w + vec2 * q1w;
+ float scalarPart = q1w * q2w - dot;
+
+ return new Quaternion(vectorPart, scalarPart);
+ }
+
+ ///
+ /// Flips the sign of each component of the quaternion.
+ ///
+ /// The source Quaternion.
+ /// The negated Quaternion.
+ public static Quaternion operator -(Quaternion value)
+ {
+ Vector4 q = Unsafe.As(ref value);
+ Vector4 result = -q;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Adds two Quaternions element-by-element.
+ ///
+ /// The first source Quaternion.
+ /// The second source Quaternion.
+ /// The result of adding the Quaternions.
+ public static Quaternion operator +(Quaternion value1, Quaternion value2)
+ {
+ Vector4 q1 = Unsafe.As(ref value1);
+ Vector4 q2 = Unsafe.As(ref value2);
+
+ Vector4 result = q1 + q2;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Subtracts one Quaternion from another.
+ ///
+ /// The first source Quaternion.
+ /// The second Quaternion, to be subtracted from the first.
+ /// The result of the subtraction.
+ public static Quaternion operator -(Quaternion value1, Quaternion value2)
+ {
+ Vector4 q1 = Unsafe.As(ref value1);
+ Vector4 q2 = Unsafe.As(ref value2);
+
+ Vector4 result = q1 - q2;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Multiplies two Quaternions together.
+ ///
+ /// The Quaternion on the left side of the multiplication.
+ /// The Quaternion on the right side of the multiplication.
+ /// The result of the multiplication.
+ public static Quaternion operator *(Quaternion value1, Quaternion value2)
+ {
+ float q1w = value1.W;
+ float q2w = value2.W;
+
+ Vector3 vec1 = Unsafe.As(ref value1);
+ Vector3 vec2 = Unsafe.As(ref value2);
+
+ float dot = Vector3.Dot(vec1, vec2);
+
+ Vector3 vectorPart = Vector3.Cross(vec1, vec2) + vec1 * q2w + vec2 * q1w;
+ float scalarPart = q1w * q2w - dot;
+
+ return new Quaternion(vectorPart, scalarPart);
+ }
+
+ ///
+ /// Multiplies a Quaternion by a scalar value.
+ ///
+ /// The source Quaternion.
+ /// The scalar value.
+ /// The result of the multiplication.
+ public static Quaternion operator *(Quaternion value1, float value2)
+ {
+ Vector4 q1 = Unsafe.As(ref value1);
+
+ Vector4 result = q1 * value2;
+
+ return Unsafe.As(ref result);
+ }
+
+ ///
+ /// Divides a Quaternion by another Quaternion.
+ ///
+ /// The source Quaternion.
+ /// The divisor.
+ /// The result of the division.
+ public static Quaternion operator /(Quaternion value1, Quaternion value2)
+ {
+ Vector4 q2 = Unsafe.As(ref value2);
+
+ // Inverse part.
+ float ls = Vector4.Dot(q2, q2);
+ float invNorm = -1.0f / ls;
+ Vector4 q = q2 * invNorm;
+ float q2w = -q.W;
+
+ // Multiply part.
+ float q1w = value1.W;
+ Vector3 vec1 = Unsafe.As(ref value1);
+ Vector3 vec2 = Unsafe.As(ref q);
+
+ float dot = Vector3.Dot(vec1, vec2);
+
+ Vector3 vectorPart = Vector3.Cross(vec1, vec2) + vec1 * q2w + vec2 * q1w;
+ float scalarPart = q1w * q2w - dot;
+
+ return new Quaternion(vectorPart, scalarPart);
+ }
+
+ ///
+ /// Returns a boolean indicating whether the two given Quaternions are equal.
+ ///
+ /// The first Quaternion to compare.
+ /// The second Quaternion to compare.
+ /// True if the Quaternions are equal; False otherwise.
+ public static bool operator ==(Quaternion value1, Quaternion value2)
+ {
+ Vector4 q1 = Unsafe.As(ref value1);
+ Vector4 q2 = Unsafe.As(ref value2);
+ return q1 == q2;
+ }
+
+ ///
+ /// Returns a boolean indicating whether the two given Quaternions are not equal.
+ ///
+ /// The first Quaternion to compare.
+ /// The second Quaternion to compare.
+ /// True if the Quaternions are not equal; False if they are equal.
+ public static bool operator !=(Quaternion value1, Quaternion value2)
+ {
+ Vector4 q1 = Unsafe.As(ref value1);
+ Vector4 q2 = Unsafe.As(ref value2);
+ return q1 != q2;
+ }
+
+ ///
+ /// Returns a boolean indicating whether the given Quaternion is equal to this Quaternion instance.
+ ///
+ /// The Quaternion to compare this instance to.
+ /// True if the other Quaternion is equal to this instance; False otherwise.
+ public bool Equals(Quaternion other)
+ {
+ Vector4 q1 = Unsafe.As(ref this);
+ Vector4 q2 = Unsafe.As(ref other);
+ return q1 == q2;
+ }
+
+ ///
+ /// Returns a boolean indicating whether the given Object is equal to this Quaternion instance.
+ ///
+ /// The Object to compare against.
+ /// True if the Object is equal to this Quaternion; False otherwise.
+ public override bool Equals(object obj)
+ {
+ if (obj is Quaternion)
+ {
+ return Equals((Quaternion)obj);
+ }
+
+ return false;
+ }
+
+ ///
+ /// Returns a String representing this Quaternion instance.
+ ///
+ /// The string representation.
+ public override string ToString()
+ {
+ CultureInfo ci = CultureInfo.CurrentCulture;
+
+ return String.Format(ci, "{{X:{0} Y:{1} Z:{2} W:{3}}}", X.ToString(ci), Y.ToString(ci), Z.ToString(ci), W.ToString(ci));
+ }
+
+ ///
+ /// Returns the hash code for this instance.
+ ///
+ /// The hash code.
+ public override int GetHashCode()
+ {
+ return unchecked(X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode());
+ }
+ }
+}
diff --git a/src/System.Numerics.Vectors/tests/QuaternionTests.cs b/src/System.Numerics.Vectors/tests/QuaternionTests.cs
index 6bb5c32e72d3..759f62a18928 100644
--- a/src/System.Numerics.Vectors/tests/QuaternionTests.cs
+++ b/src/System.Numerics.Vectors/tests/QuaternionTests.cs
@@ -21,7 +21,7 @@ public void QuaternionDotTest()
float actual;
actual = Quaternion.Dot(a, b);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Dot did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Dot did not return the expected value: expected {expected} actual {actual}");
}
// A test for Length ()
@@ -39,7 +39,7 @@ public void QuaternionLengthTest()
actual = target.Length();
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Length did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Length did not return the expected value: expected {expected} actual {actual}");
}
// A test for LengthSquared ()
@@ -56,7 +56,7 @@ public void QuaternionLengthSquaredTest()
actual = target.LengthSquared();
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.LengthSquared did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.LengthSquared did not return the expected value: expected {expected} actual {actual}");
}
// A test for Lerp (Quaternion, Quaternion, float)
@@ -73,12 +73,12 @@ public void QuaternionLerpTest()
Quaternion actual;
actual = Quaternion.Lerp(a, b, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Lerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Lerp did not return the expected value: expected {expected} actual {actual}");
// Case a and b are same.
expected = a;
actual = Quaternion.Lerp(a, a, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Lerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Lerp did not return the expected value: expected {expected} actual {actual}");
}
// A test for Lerp (Quaternion, Quaternion, float)
@@ -94,7 +94,7 @@ public void QuaternionLerpTest1()
Quaternion expected = new Quaternion(a.X, a.Y, a.Z, a.W);
Quaternion actual = Quaternion.Lerp(a, b, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Lerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Lerp did not return the expected value: expected {expected} actual {actual}");
}
// A test for Lerp (Quaternion, Quaternion, float)
@@ -110,7 +110,7 @@ public void QuaternionLerpTest2()
Quaternion expected = new Quaternion(b.X, b.Y, b.Z, b.W);
Quaternion actual = Quaternion.Lerp(a, b, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Lerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Lerp did not return the expected value: expected {expected} actual {actual}");
}
// A test for Lerp (Quaternion, Quaternion, float)
@@ -128,7 +128,7 @@ public void QuaternionLerpTest3()
// Note that in quaternion world, Q == -Q. In the case of quaternions dot product is zero,
// one of the quaternion will be flipped to compute the shortest distance. When t = 1, we
// expect the result to be the same as quaternion b but flipped.
- Assert.True(actual == a, "Quaternion.Lerp did not return the expected value.");
+ Assert.True(actual == a, $"Quaternion.Lerp did not return the expected value: expected {a} actual {actual}");
}
// A test for Conjugate(Quaternion)
@@ -141,7 +141,7 @@ public void QuaternionConjugateTest1()
Quaternion actual;
actual = Quaternion.Conjugate(a);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Conjugate did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Conjugate did not return the expected value: expected {expected} actual {actual}");
}
// A test for Normalize (Quaternion)
@@ -154,7 +154,7 @@ public void QuaternionNormalizeTest()
Quaternion actual;
actual = Quaternion.Normalize(a);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Normalize did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Normalize did not return the expected value: expected {expected} actual {actual}");
}
// A test for Normalize (Quaternion)
@@ -166,7 +166,7 @@ public void QuaternionNormalizeTest1()
Quaternion actual = Quaternion.Normalize(a);
Assert.True(float.IsNaN(actual.X) && float.IsNaN(actual.Y) && float.IsNaN(actual.Z) && float.IsNaN(actual.W)
- , "Quaternion.Normalize did not return the expected value.");
+ , $"Quaternion.Normalize did not return the expected value: expected {new Quaternion(float.NaN, float.NaN, float.NaN, float.NaN)} actual {actual}");
}
// A test for Concatenate(Quaternion, Quaternion)
@@ -180,7 +180,7 @@ public void QuaternionConcatenateTest1()
Quaternion actual;
actual = Quaternion.Concatenate(a, b);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Concatenate did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Concatenate did not return the expected value: expected {expected} actual {actual}");
}
// A test for operator - (Quaternion, Quaternion)
@@ -195,7 +195,7 @@ public void QuaternionSubtractionTest()
actual = a - b;
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.operator - did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.operator - did not return the expected value: expected {expected} actual {actual}");
}
// A test for operator * (Quaternion, float)
@@ -210,7 +210,7 @@ public void QuaternionMultiplyTest()
actual = a * factor;
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.operator * did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.operator * did not return the expected value: expected {expected} actual {actual}");
}
// A test for operator * (Quaternion, Quaternion)
@@ -225,7 +225,7 @@ public void QuaternionMultiplyTest1()
actual = a * b;
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.operator * did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.operator * did not return the expected value: expected {expected} actual {actual}");
}
// A test for operator / (Quaternion, Quaternion)
@@ -240,7 +240,7 @@ public void QuaternionDivisionTest1()
actual = a / b;
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.operator / did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.operator / did not return the expected value: expected {expected} actual {actual}");
}
// A test for operator + (Quaternion, Quaternion)
@@ -255,7 +255,7 @@ public void QuaternionAdditionTest()
actual = a + b;
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.operator + did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.operator + did not return the expected value: expected {expected} actual {actual}");
}
// A test for Quaternion (float, float, float, float)
@@ -296,7 +296,7 @@ public void QuaternionCreateFromAxisAngleTest()
Quaternion actual;
actual = Quaternion.CreateFromAxisAngle(axis, angle);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.CreateFromAxisAngle did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.CreateFromAxisAngle did not return the expected value: expected {expected} actual {actual}");
}
// A test for CreateFromAxisAngle (Vector3f, float)
@@ -325,7 +325,7 @@ public void QuaternionCreateFromAxisAngleTest2()
Quaternion actual1 = Quaternion.CreateFromAxisAngle(axis, angle1);
Quaternion actual2 = Quaternion.CreateFromAxisAngle(axis, angle2);
- Assert.True(MathHelper.Equal(actual1, actual2), "Quaternion.CreateFromAxisAngle did not return the expected value.");
+ Assert.True(MathHelper.Equal(actual1, actual2), $"Quaternion.CreateFromAxisAngle did not return the expected value: actual1 {actual1} actual2 {actual2}");
}
// A test for CreateFromAxisAngle (Vector3f, float)
@@ -342,7 +342,7 @@ public void QuaternionCreateFromAxisAngleTest3()
actual1.X = -actual1.X;
actual1.W = -actual1.W;
- Assert.True(MathHelper.Equal(actual1, actual2), "Quaternion.CreateFromAxisAngle did not return the expected value.");
+ Assert.True(MathHelper.Equal(actual1, actual2), $"Quaternion.CreateFromAxisAngle did not return the expected value: actual1 {actual1} actual2 {actual2}");
}
[Fact]
@@ -358,7 +358,7 @@ public void QuaternionCreateFromYawPitchRollTest1()
Quaternion expected = yaw * pitch * roll;
Quaternion actual = Quaternion.CreateFromYawPitchRoll(yawAngle, pitchAngle, rollAngle);
- Assert.True(MathHelper.Equal(expected, actual));
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.QuaternionCreateFromYawPitchRollTest1 did not return the expected value: expected {expected} actual {actual}");
}
// Covers more numeric rigions
@@ -383,7 +383,7 @@ public void QuaternionCreateFromYawPitchRollTest2()
Quaternion expected = yaw * pitch * roll;
Quaternion actual = Quaternion.CreateFromYawPitchRoll(yawRad, pitchRad, rollRad);
- Assert.True(MathHelper.Equal(expected, actual), String.Format("Yaw:{0} Pitch:{1} Roll:{2}", yawAngle, pitchAngle, rollAngle));
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.QuaternionCreateFromYawPitchRollTest2 Yaw:{yawAngle} Pitch:{pitchAngle} Roll:{rollAngle} did not return the expected value: expected {expected} actual {actual}");
}
}
}
@@ -403,12 +403,12 @@ public void QuaternionSlerpTest()
Quaternion actual;
actual = Quaternion.Slerp(a, b, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Slerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Slerp did not return the expected value: expected {expected} actual {actual}");
// Case a and b are same.
expected = a;
actual = Quaternion.Slerp(a, a, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Slerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Slerp did not return the expected value: expected {expected} actual {actual}");
}
// A test for Slerp (Quaternion, Quaternion, float)
@@ -424,7 +424,7 @@ public void QuaternionSlerpTest1()
Quaternion expected = new Quaternion(a.X, a.Y, a.Z, a.W);
Quaternion actual = Quaternion.Slerp(a, b, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Slerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Slerp did not return the expected value: expected {expected} actual {actual}");
}
// A test for Slerp (Quaternion, Quaternion, float)
@@ -440,7 +440,7 @@ public void QuaternionSlerpTest2()
Quaternion expected = new Quaternion(b.X, b.Y, b.Z, b.W);
Quaternion actual = Quaternion.Slerp(a, b, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Slerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Slerp did not return the expected value: expected {expected} actual {actual}");
}
// A test for Slerp (Quaternion, Quaternion, float)
@@ -459,7 +459,7 @@ public void QuaternionSlerpTest3()
// Note that in quaternion world, Q == -Q. In the case of quaternions dot product is zero,
// one of the quaternion will be flipped to compute the shortest distance. When t = 1, we
// expect the result to be the same as quaternion b but flipped.
- Assert.True(actual == expected, "Quaternion.Slerp did not return the expected value.");
+ Assert.True(actual == expected, $"Quaternion.Slerp did not return the expected value: expected {expected} actual {actual}");
}
// A test for Slerp (Quaternion, Quaternion, float)
@@ -475,7 +475,7 @@ public void QuaternionSlerpTest4()
Quaternion expected = new Quaternion(a.X, a.Y, a.Z, a.W);
Quaternion actual = Quaternion.Slerp(a, b, t);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Slerp did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Slerp did not return the expected value: expected {expected} actual {actual}");
}
// A test for operator - (Quaternion)
@@ -489,7 +489,7 @@ public void QuaternionUnaryNegationTest()
actual = -a;
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.operator - did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.operator - did not return the expected value: expected {expected} actual {actual}");
}
// A test for Inverse (Quaternion)
@@ -514,7 +514,7 @@ public void QuaternionInverseTest1()
Quaternion actual = Quaternion.Inverse(a);
Assert.True(float.IsNaN(actual.X) && float.IsNaN(actual.Y) && float.IsNaN(actual.Z) && float.IsNaN(actual.W)
- );
+ , $"Quaternion.Inverse - did not return the expected value: expected {new Quaternion(float.NaN, float.NaN, float.NaN, float.NaN)} actual {actual}");
}
// A test for ToString ()
@@ -556,7 +556,7 @@ public void QuaternionDivideTest()
Quaternion actual;
actual = Quaternion.Divide(a, b);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Divide did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Divide did not return the expected value: expected {expected} actual {actual}");
}
// A test for Equals (object)
@@ -615,7 +615,7 @@ public void QuaternionMultiplyTest2()
Quaternion actual;
actual = Quaternion.Multiply(a, factor);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Multiply did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Multiply did not return the expected value: expected {expected} actual {actual}");
}
// A test for Multiply (Quaternion, Quaternion)
@@ -629,7 +629,7 @@ public void QuaternionMultiplyTest3()
Quaternion actual;
actual = Quaternion.Multiply(a, b);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.Multiply did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual), $"Quaternion.Multiply did not return the expected value: expected {expected} actual {actual}");
}
// A test for Negate (Quaternion)
@@ -706,11 +706,13 @@ public void QuaternionFromRotationMatrixTest1()
Quaternion expected = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
Quaternion actual = Quaternion.CreateFromRotationMatrix(matrix);
- Assert.True(MathHelper.Equal(expected, actual), "Quaternion.CreateFromRotationMatrix did not return the expected value.");
+ Assert.True(MathHelper.Equal(expected, actual),
+ $"Quaternion.CreateFromRotationMatrix did not return the expected value: expected {expected} actual {actual}");
// make sure convert back to matrix is same as we passed matrix.
Matrix4x4 m2 = Matrix4x4.CreateFromQuaternion(actual);
- Assert.True(MathHelper.Equal(matrix, m2), "Quaternion.CreateFromRotationMatrix did not return the expected value.");
+ Assert.True(MathHelper.Equal(matrix, m2),
+ $"Quaternion.CreateFromQuaternion did not return the expected value: matrix {matrix} m2 {m2}");
}
// A test for CreateFromRotationMatrix (Matrix4x4)
@@ -725,14 +727,12 @@ public void QuaternionFromRotationMatrixTest2()
Quaternion expected = Quaternion.CreateFromAxisAngle(Vector3.UnitX, angle);
Quaternion actual = Quaternion.CreateFromRotationMatrix(matrix);
Assert.True(MathHelper.EqualRotation(expected, actual),
- string.Format("Quaternion.CreateFromRotationMatrix did not return the expected value. angle:{0} expected:{1} actual:{2}",
- angle.ToString(), expected.ToString(), actual.ToString()));
+ $"Quaternion.CreateFromRotationMatrix angle:{angle} did not return the expected value: expected {expected} actual {actual}");
// make sure convert back to matrix is same as we passed matrix.
Matrix4x4 m2 = Matrix4x4.CreateFromQuaternion(actual);
Assert.True(MathHelper.Equal(matrix, m2),
- string.Format("Quaternion.CreateFromRotationMatrix did not return the expected value. angle:{0} expected:{1} actual:{2}",
- angle.ToString(), matrix.ToString(), m2.ToString()));
+ $"Quaternion.CreateFromQuaternion angle:{angle} did not return the expected value: matrix {matrix} m2 {m2}");
}
}
@@ -748,14 +748,12 @@ public void QuaternionFromRotationMatrixTest3()
Quaternion expected = Quaternion.CreateFromAxisAngle(Vector3.UnitY, angle);
Quaternion actual = Quaternion.CreateFromRotationMatrix(matrix);
Assert.True(MathHelper.EqualRotation(expected, actual),
- string.Format("Quaternion.CreateFromRotationMatrix did not return the expected value. angle:{0}",
- angle.ToString()));
+ $"Quaternion.CreateFromRotationMatrix angle:{angle} did not return the expected value: expected {expected} actual {actual}");
// make sure convert back to matrix is same as we passed matrix.
Matrix4x4 m2 = Matrix4x4.CreateFromQuaternion(actual);
Assert.True(MathHelper.Equal(matrix, m2),
- string.Format("Quaternion.CreateFromRotationMatrix did not return the expected value. angle:{0}",
- angle.ToString()));
+ $"Quaternion.CreateFromQuaternion angle:{angle} did not return the expected value: matrix {matrix} m2 {m2}");
}
}
@@ -771,14 +769,12 @@ public void QuaternionFromRotationMatrixTest4()
Quaternion expected = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, angle);
Quaternion actual = Quaternion.CreateFromRotationMatrix(matrix);
Assert.True(MathHelper.EqualRotation(expected, actual),
- string.Format("Quaternion.CreateFromRotationMatrix did not return the expected value. angle:{0} expected:{1} actual:{2}",
- angle.ToString(), expected.ToString(), actual.ToString()));
+ $"Quaternion.CreateFromRotationMatrix angle:{angle} did not return the expected value: expected {expected} actual {actual}");
// make sure convert back to matrix is same as we passed matrix.
Matrix4x4 m2 = Matrix4x4.CreateFromQuaternion(actual);
Assert.True(MathHelper.Equal(matrix, m2),
- string.Format("Quaternion.CreateFromRotationMatrix did not return the expected value. angle:{0} expected:{1} actual:{2}",
- angle.ToString(), matrix.ToString(), m2.ToString()));
+ $"Quaternion.CreateFromQuaternion angle:{angle} did not return the expected value: matrix {matrix} m2 {m2}");
}
}
@@ -798,14 +794,12 @@ public void QuaternionFromRotationMatrixTest5()
Quaternion actual = Quaternion.CreateFromRotationMatrix(matrix);
Assert.True(MathHelper.EqualRotation(expected, actual),
- string.Format("Quaternion.CreateFromRotationMatrix did not return the expected value. angle:{0} expected:{1} actual:{2}",
- angle.ToString(), expected.ToString(), actual.ToString()));
+ $"Quaternion.CreateFromRotationMatrix angle:{angle} did not return the expected value: expected {expected} actual {actual}");
// make sure convert back to matrix is same as we passed matrix.
Matrix4x4 m2 = Matrix4x4.CreateFromQuaternion(actual);
Assert.True(MathHelper.Equal(matrix, m2),
- string.Format("Quaternion.CreateFromRotationMatrix did not return the expected value. angle:{0} expected:{1} actual:{2}",
- angle.ToString(), matrix.ToString(), m2.ToString()));
+ $"Quaternion.CreateFromQuaternion angle:{angle} did not return the expected value: matrix {matrix} m2 {m2}");
}
}
@@ -819,11 +813,13 @@ public void QuaternionFromRotationMatrixWithScaledMatrixTest1()
Quaternion expected = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, angle) * Quaternion.CreateFromAxisAngle(Vector3.UnitY, angle);
Quaternion actual = Quaternion.CreateFromRotationMatrix(matrix);
- Assert.True(MathHelper.EqualRotation(expected, actual), "Quaternion.CreateFromRotationMatrix did not return the expected value.");
+ Assert.True(MathHelper.EqualRotation(expected, actual),
+ $"Quaternion.CreateFromRotationMatrix did not return the expected value: expected {expected} actual {actual}");
// make sure convert back to matrix is same as we passed matrix.
Matrix4x4 m2 = Matrix4x4.CreateFromQuaternion(actual);
- Assert.True(MathHelper.Equal(matrix, m2), "Quaternion.CreateFromRotationMatrix did not return the expected value.");
+ Assert.True(MathHelper.Equal(matrix, m2),
+ $"Quaternion.CreateFromQuaternion did not return the expected value: matrix {matrix} m2 {m2}");
}
// A test for CreateFromRotationMatrix (Matrix4x4)
@@ -836,11 +832,13 @@ public void QuaternionFromRotationMatrixWithScaledMatrixTest2()
Quaternion expected = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, angle) * Quaternion.CreateFromAxisAngle(Vector3.UnitX, angle);
Quaternion actual = Quaternion.CreateFromRotationMatrix(matrix);
- Assert.True(MathHelper.EqualRotation(expected, actual), "Quaternion.CreateFromRotationMatrix did not return the expected value.");
+ Assert.True(MathHelper.EqualRotation(expected, actual),
+ $"Quaternion.CreateFromRotationMatrix did not return the expected value: expected {expected} actual {actual}");
// make sure convert back to matrix is same as we passed matrix.
Matrix4x4 m2 = Matrix4x4.CreateFromQuaternion(actual);
- Assert.True(MathHelper.Equal(matrix, m2), "Quaternion.CreateFromRotationMatrix did not return the expected value.");
+ Assert.True(MathHelper.Equal(matrix, m2),
+ $"Quaternion.CreateFromQuaternion did not return the expected value: matrix {matrix} m2 {m2}");
}
// A test for CreateFromRotationMatrix (Matrix4x4)
@@ -853,11 +851,13 @@ public void QuaternionFromRotationMatrixWithScaledMatrixTest3()
Quaternion expected = Quaternion.CreateFromAxisAngle(Vector3.UnitY, angle) * Quaternion.CreateFromAxisAngle(Vector3.UnitX, angle);
Quaternion actual = Quaternion.CreateFromRotationMatrix(matrix);
- Assert.True(MathHelper.EqualRotation(expected, actual), "Quaternion.CreateFromRotationMatrix did not return the expected value.");
+ Assert.True(MathHelper.EqualRotation(expected, actual),
+ $"Quaternion.CreateFromRotationMatrix did not return the expected value: expected {expected} actual {actual}");
// make sure convert back to matrix is same as we passed matrix.
Matrix4x4 m2 = Matrix4x4.CreateFromQuaternion(actual);
- Assert.True(MathHelper.Equal(matrix, m2), "Quaternion.CreateFromRotationMatrix did not return the expected value.");
+ Assert.True(MathHelper.Equal(matrix, m2),
+ $"Quaternion.CreateFromQuaternion did not return the expected value: matrix {matrix} m2 {m2}");
}
// A test for Equals (Quaternion)