public void Constructor() { QuaternionD q = new QuaternionD(1, 2, 3, 4); Assert.AreEqual(1.0, q.W); Assert.AreEqual(2.0, q.X); Assert.AreEqual(3.0, q.Y); Assert.AreEqual(4.0, q.Z); q = new QuaternionD(new double[] { 1, 2, 3, 4 }); Assert.AreEqual(1.0, q.W); Assert.AreEqual(2.0, q.X); Assert.AreEqual(3.0, q.Y); Assert.AreEqual(4.0, q.Z); q = new QuaternionD(new List <double>(new double[] { 1, 2, 3, 4 })); Assert.AreEqual(1.0, q.W); Assert.AreEqual(2.0, q.X); Assert.AreEqual(3.0, q.Y); Assert.AreEqual(4.0, q.Z); // From matrix q = QuaternionD.CreateRotation(Matrix33D.Identity); Assert.AreEqual(QuaternionD.Identity, q); q = new QuaternionD(0.123, new Vector3D(1.0, 2.0, 3.0)); Assert.AreEqual(0.123, q.W); Assert.AreEqual(1.0, q.X); Assert.AreEqual(2.0, q.Y); Assert.AreEqual(3.0, q.Z); }
public void CreateRotationX() { double angle = 0.3; QuaternionD q = QuaternionD.CreateRotation(Vector3D.UnitX, angle); QuaternionD qx = QuaternionD.CreateRotationX(angle); Assert.AreEqual(q, qx); }
public void CreateRotationY() { double angle = 0.3; QuaternionD q = QuaternionD.CreateRotation(Vector3D.UnitY, angle); QuaternionD qy = QuaternionD.CreateRotationY(angle); Assert.AreEqual(q, qy); }
public void CreateRotationZ() { double angle = 0.3; QuaternionD q = QuaternionD.CreateRotation(Vector3D.UnitZ, angle); QuaternionD qz = QuaternionD.CreateRotationZ(angle); Assert.AreEqual(q, qz); }
public void RotationMatrix44() { double angle = -1.6; Vector3D axis = new Vector3D(1.0, 2.0, -3.0); QuaternionD q = QuaternionD.CreateRotation(axis, angle); Matrix44D m44 = Matrix44D.CreateRotation(axis, angle); Assert.IsTrue(Matrix44D.AreNumericallyEqual(q.ToRotationMatrix44(), m44)); }
/// <summary> /// Gets a random unit <see cref="QuaternionD"/>. /// </summary> /// <param name="random"> /// The random number generator. If this parameter is <see langword="null"/>, the global random /// number generator (see <see cref="RandomHelper.Random"/>) is used. /// </param> /// <returns>A random unit <see cref="QuaternionD"/>;.</returns> public static QuaternionD NextQuaternionD(this Random random) { if (random == null) { random = Random; } return(QuaternionD.CreateRotation(NextVector3D(random, -1, 1), NextDouble(random, 0, 2 * Math.PI))); }
public void FromMatrixWithZeroTrace() { QuaternionD q; Matrix33D m = new Matrix33D(0, 1, 0, 0, 0, 1, 1, 0, 0); q = QuaternionD.CreateRotation(m); Assert.IsTrue(QuaternionD.AreNumericallyEqual(new QuaternionD(-0.5, 0.5, 0.5, 0.5), q)); }
public void Angle() { Vector3D axis = new Vector3D(1.0, 2.0, 3.0); QuaternionD q = QuaternionD.CreateRotation(axis, 0.4); Assert.IsTrue(Numeric.AreEqual(0.4, q.Angle)); q.Angle = 0.9; Assert.IsTrue(QuaternionD.AreNumericallyEqual(q, QuaternionD.CreateRotation(axis, 0.9))); Assert.AreEqual(0, new QuaternionD(1.00000001f, 0, 0, 0).Angle); }
public void CreateRotationZ() { double angle = (double)MathHelper.ToRadians(30); Matrix33D m = Matrix33D.CreateRotationZ(angle); Assert.IsTrue(Vector3D.AreNumericallyEqual(new Vector3D((double)Math.Cos(angle), (double)Math.Sin(angle), 0), m * Vector3D.UnitX)); QuaternionD q = QuaternionD.CreateRotation(Vector3D.UnitZ, angle); Assert.IsTrue(Vector3D.AreNumericallyEqual(q.Rotate(Vector3D.One), m * Vector3D.One)); Assert.IsTrue(Matrix33D.AreNumericallyEqual(Matrix33D.CreateRotation(Vector3D.UnitZ, angle), m)); }
public void SlerpNegatedDoublePrecision() { QuaternionD q1 = new QuaternionD(-1.0, 0.0, 0.0, 0.0); QuaternionD q2 = QuaternionD.CreateRotation(-Vector3.UnitZ, -Math.PI / 2); QuaternionD slerp = InterpolationHelper.Slerp(q1, q2, 0.5); Assert.IsTrue(slerp.IsNumericallyNormalized); Vector3D v = slerp.Rotate(Vector3D.UnitX); Vector3D result = new Vector3D(1.0, 1.0, 0.0).Normalized; Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); }
public void SlerpXDoublePrecision() { QuaternionD q1 = QuaternionD.Identity; QuaternionD q2 = QuaternionD.CreateRotation(Vector3.UnitX, Math.PI / 2); QuaternionD slerp = InterpolationHelper.Slerp(q1, q2, 0.5); Assert.IsTrue(slerp.IsNumericallyNormalized); Vector3D v = slerp.Rotate(Vector3.UnitY); Vector3D result = new Vector3D(0.0, 1.0, 1.0).Normalized; Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); }
public void RotationMatrix33() { double angle = -1.6; Vector3D axis = new Vector3D(1.0, 2.0, -3.0); QuaternionD q = QuaternionD.CreateRotation(axis, angle); Matrix33D m33 = Matrix33D.CreateRotation(axis, angle); Vector3D v = new Vector3D(0.3, -2.4, 5.6); Vector3D result1 = q.ToRotationMatrix33() * v; Vector3D result2 = m33 * v; Assert.IsTrue(Vector3D.AreNumericallyEqual(result1, result2)); }
/// <summary> /// Interpolates two poses. /// </summary> /// <param name="startPose">The start pose.</param> /// <param name="endPose">The end pose.</param> /// <param name="parameter"> /// The interpolation parameter. If the value is 0, the <paramref name="startPose"/> is /// returned. If the value is 1, the <paramref name="endPose"/> is returned. For values between /// 0 and 1 an interpolated pose is returned. /// </param> /// <returns>An interpolated pose.</returns> public static PoseD Interpolate(PoseD startPose, PoseD endPose, double parameter) { // Linearly interpolate position. var interpolatedPosition = startPose.Position * (1 - parameter) + endPose.Position * parameter; // Slerp orientation. var interpolatedOrientation = InterpolationHelper.Lerp( QuaternionD.CreateRotation(startPose.Orientation), QuaternionD.CreateRotation(endPose.Orientation), parameter); return(new PoseD(interpolatedPosition, interpolatedOrientation)); }
public void QuaternionDFromMatrix33() { Vector3D v = Vector3D.One; Matrix33D m = Matrix33D.Identity; QuaternionD q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = Matrix33D.CreateRotation(Vector3D.UnitX, 0.3); q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = Matrix33D.CreateRotation(Vector3D.UnitY, 1.0); q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = Matrix33D.CreateRotation(Vector3D.UnitZ, 4.0); q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = Matrix33D.Identity; q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = Matrix33D.CreateRotation(-Vector3D.UnitX, 1.3); q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = Matrix33D.CreateRotation(-Vector3D.UnitY, -1.4); q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = Matrix33D.CreateRotation(-Vector3D.UnitZ, -0.1); q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = new Matrix33D(0, 0, 1, 0, -1, 0, 1, 0, 0); q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); m = new Matrix33D(-1, 0, 0, 0, 1, 0, 0, 0, -1); q = QuaternionD.CreateRotation(m); Assert.IsTrue(Vector3D.AreNumericallyEqual(m * v, q.Rotate(v))); }
public void Interpolate() { PoseD p1 = new PoseD(new Vector3D(1, 2, 3), QuaternionD.CreateRotationY(0.3)); PoseD p2 = new PoseD(new Vector3D(-4, 5, -6), QuaternionD.CreateRotationZ(-0.1)); Assert.IsTrue(Vector3D.AreNumericallyEqual(p1.Position, PoseD.Interpolate(p1, p2, 0).Position)); Assert.IsTrue(Matrix33D.AreNumericallyEqual(p1.Orientation, PoseD.Interpolate(p1, p2, 0).Orientation)); Assert.IsTrue(Vector3D.AreNumericallyEqual(p2.Position, PoseD.Interpolate(p1, p2, 1).Position)); Assert.IsTrue(Matrix33D.AreNumericallyEqual(p2.Orientation, PoseD.Interpolate(p1, p2, 1).Orientation)); Assert.IsTrue(Vector3D.AreNumericallyEqual(InterpolationHelper.Lerp(p1.Position, p2.Position, 0.3), PoseD.Interpolate(p1, p2, 0.3).Position)); Assert.IsTrue( QuaternionD.AreNumericallyEqual( InterpolationHelper.Lerp(QuaternionD.CreateRotation(p1.Orientation), QuaternionD.CreateRotation(p2.Orientation), 0.3), QuaternionD.CreateRotation(PoseD.Interpolate(p1, p2, 0.3).Orientation))); }
public void Division() { double angle1 = 0.4; Vector3D axis1 = new Vector3D(1.0, 2.0, 3.0); QuaternionD q1 = QuaternionD.CreateRotation(axis1, angle1); Matrix33D m1 = Matrix33D.CreateRotation(axis1, angle1); double angle2 = -1.6; Vector3D axis2 = new Vector3D(1.0, -2.0, -3.5); QuaternionD q2 = QuaternionD.CreateRotation(axis2, angle2); Matrix33D m2 = Matrix33D.CreateRotation(axis2, angle2); Vector3D v = new Vector3D(0.3, -2.4, 5.6); Vector3D result1 = QuaternionD.Divide(q2, q1).Rotate(v); Vector3D result2 = m2 * m1.Inverse * v; Assert.IsTrue(Vector3D.AreNumericallyEqual(result1, result2)); }
public void LerpQuaternionD() { // Warning: The not all results are not verified QuaternionD q1 = new QuaternionD(1.0, 2.0, 3.0, 4.0).Normalized; QuaternionD q2 = new QuaternionD(2.0, 4.0, 6.0, 8.0).Normalized; QuaternionD lerp = InterpolationHelper.Lerp(q1, q2, 0.75); Assert.IsTrue(lerp.IsNumericallyNormalized); lerp = InterpolationHelper.Lerp(q1, q2, 0); Assert.IsTrue(QuaternionD.AreNumericallyEqual(q1, lerp)); lerp = InterpolationHelper.Lerp(q1, q2, 1); Assert.IsTrue(QuaternionD.AreNumericallyEqual(q2, lerp)); q1 = QuaternionD.Identity; q2 = QuaternionD.CreateRotation(Vector3D.UnitZ, Math.PI / 2); lerp = InterpolationHelper.Lerp(q1, q2, 0.5); Vector3D v = lerp.Rotate(Vector3D.UnitX); Vector3D result = new Vector3D(1.0, 1.0, 0.0).Normalized; Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); q1 = QuaternionD.Identity; q2 = QuaternionD.CreateRotation(Vector3D.UnitY, Math.PI / 2); lerp = InterpolationHelper.Lerp(q1, q2, 0.5); v = lerp.Rotate(Vector3D.UnitZ); result = new Vector3D(1.0, 0.0, 1.0).Normalized; Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); q1 = QuaternionD.Identity; q2 = QuaternionD.CreateRotation(Vector3D.UnitX, Math.PI / 2); lerp = InterpolationHelper.Lerp(q1, q2, 0.5); v = lerp.Rotate(Vector3D.UnitY); result = new Vector3D(0.0, 1.0, 1.0).Normalized; Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); q1 = new QuaternionD(-1.0, 0.0, 0.0, 0.0); q2 = QuaternionD.CreateRotation(-Vector3D.UnitZ, -Math.PI / 2); lerp = InterpolationHelper.Lerp(q1, q2, 0.5); v = lerp.Rotate(Vector3D.UnitX); result = new Vector3D(1.0, 1.0, 0.0).Normalized; Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); }
public void Axis() { Vector3D axis = new Vector3D(1.0, 2.0, 3.0); double angle = 0.2; QuaternionD q = QuaternionD.CreateRotation(axis, angle); Assert.IsTrue(Numeric.AreEqual(angle, q.Angle)); Assert.IsTrue(Vector3D.AreNumericallyEqual(axis.Normalized, q.Axis)); axis = new Vector3D(1.0, 1.0, 1.0); q.Axis = axis; Assert.IsTrue(Numeric.AreEqual(angle, q.Angle)); Assert.IsTrue(Vector3D.AreNumericallyEqual(axis.Normalized, q.Axis)); Assert.IsTrue(Vector3D.AreNumericallyEqual(Matrix33D.CreateRotation(axis, angle) * Vector3D.One, q.Rotate(Vector3D.One))); Assert.AreEqual(Vector3D.Zero, QuaternionD.Identity.Axis); q.Axis = Vector3D.Zero; Assert.AreEqual(QuaternionD.Identity, q); }
public void SlerpGeneralDoublePrecision() { QuaternionD q1 = QuaternionD.CreateRotation(-Vector3D.UnitY, Math.PI / 2); QuaternionD q2 = QuaternionD.CreateRotation(Vector3D.UnitZ, Math.PI / 2); QuaternionD slerp = InterpolationHelper.Slerp(q1, q2, 0.5); Assert.IsTrue(slerp.IsNumericallyNormalized); Vector3D v = slerp.Rotate(Vector3D.UnitX); Vector3D result = new Vector3D(1.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0); // I hope this is correct. Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); q1 = QuaternionD.CreateRotation(-Vector3D.UnitY, Math.PI / 2); q2 = QuaternionD.CreateRotation(-Vector3D.UnitZ, -Math.PI / 2); slerp = InterpolationHelper.Slerp(q1, q2, 0.5); Assert.IsTrue(slerp.IsNumericallyNormalized); v = slerp.Rotate(Vector3D.UnitX); result = new Vector3D(1.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0); // I hope this is correct. Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); }
public void Inverse() { QuaternionD identity = QuaternionD.Identity; QuaternionD inverseIdentity = identity.Inverse; Assert.AreEqual(inverseIdentity, identity); double angle = 0.4; Vector3D axis = new Vector3D(1.0, 1.0, 1.0); axis.Normalize(); QuaternionD q = QuaternionD.CreateRotation(axis, angle); QuaternionD inverse = q.Inverse; Assert.IsTrue(Vector3D.AreNumericallyEqual(-axis, inverse.Axis)); q = new QuaternionD(1, 2, 3, 4); inverse = q.Inverse; Assert.IsTrue(QuaternionD.AreNumericallyEqual(QuaternionD.Identity, inverse * q)); }
public void SquadDoublePrecision() { QuaternionD q0 = QuaternionD.CreateRotation(new Vector3D(1, 1, 1), 0.3); QuaternionD q1 = QuaternionD.CreateRotation(new Vector3D(1, 0, 1), 0.4); QuaternionD q2 = QuaternionD.CreateRotation(new Vector3D(1, 0, -1), -0.6); QuaternionD q3 = QuaternionD.CreateRotation(new Vector3D(0, 1, 1), 0.2); QuaternionD q, a, b, p; QuaternionD expected; InterpolationHelper.SquadSetup(q0, q1, q2, q3, out q, out a, out b, out p); // t = 0 QuaternionD result = InterpolationHelper.Squad(q, a, b, p, 0.0); Assert.IsTrue(QuaternionD.AreNumericallyEqual(q1, result)); // t = 1.0f result = InterpolationHelper.Squad(q, a, b, p, 1.0); Assert.IsTrue(QuaternionD.AreNumericallyEqual(q2, result)); // Check series (just for debugging) QuaternionD r1, r2, r3, r4, r5, r6, r7, r8, r9; r1 = InterpolationHelper.Squad(q, a, b, p, 0.1); r2 = InterpolationHelper.Squad(q, a, b, p, 0.2); r3 = InterpolationHelper.Squad(q, a, b, p, 0.3); r4 = InterpolationHelper.Squad(q, a, b, p, 0.4); r5 = InterpolationHelper.Squad(q, a, b, p, 0.5); r6 = InterpolationHelper.Squad(q, a, b, p, 0.6); r7 = InterpolationHelper.Squad(q, a, b, p, 0.7); r8 = InterpolationHelper.Squad(q, a, b, p, 0.8); r9 = InterpolationHelper.Squad(q, a, b, p, 0.9); // q0 = q1, q2 = q3 InterpolationHelper.SquadSetup(q1, q1, q2, q2, out q, out a, out b, out p); result = InterpolationHelper.Squad(q, a, b, p, 0.5); expected = InterpolationHelper.Slerp(q1, q2, 0.5); Assert.IsTrue(QuaternionD.AreNumericallyEqual(expected, result)); }
public void GetAngleTest() { QuaternionD qIdentity = QuaternionD.Identity; QuaternionD q03 = QuaternionD.CreateRotation(Vector3D.UnitX, 0.3); QuaternionD q03Plus11 = QuaternionD.CreateRotation(new Vector3D(1, 0.2, -3), 1.1) * q03; QuaternionD q0 = QuaternionD.CreateRotation(Vector3D.UnitX, 0.0); QuaternionD qPi = QuaternionD.CreateRotation(Vector3D.UnitX, ConstantsD.Pi); QuaternionD q2Pi = QuaternionD.CreateRotation(Vector3D.UnitX, ConstantsD.TwoPi); Assert.IsTrue(Numeric.AreEqual(0.0, QuaternionD.GetAngle(qIdentity, qIdentity))); Assert.IsTrue(Numeric.AreEqual(0.3, QuaternionD.GetAngle(qIdentity, q03))); Assert.IsTrue(Numeric.AreEqual(0.3, QuaternionD.GetAngle(qIdentity, -q03))); // Remember: q and -q represent the same orientation. Assert.IsTrue(Numeric.AreEqual(1.1, QuaternionD.GetAngle(q03, q03Plus11))); Assert.IsTrue(Numeric.AreEqual(1.1, QuaternionD.GetAngle(-q03, q03Plus11))); Assert.IsTrue(Numeric.AreEqual(1.1, QuaternionD.GetAngle(q03, -q03Plus11))); Assert.IsTrue(Numeric.AreEqual(1.1, QuaternionD.GetAngle(-q03, -q03Plus11))); Assert.IsTrue(Numeric.AreEqual(0.0, QuaternionD.GetAngle(qIdentity, q0))); Assert.IsTrue(Numeric.AreEqual(0.0, QuaternionD.GetAngle(qIdentity, q2Pi))); Assert.IsTrue(Numeric.AreEqual(0.0, QuaternionD.GetAngle(q0, q2Pi))); Assert.IsTrue(Numeric.AreEqual(0.3, QuaternionD.GetAngle(q03, q0))); Assert.IsTrue(Numeric.AreEqual(ConstantsD.Pi, QuaternionD.GetAngle(q0, qPi))); Assert.IsTrue(Numeric.AreEqual(ConstantsD.Pi, QuaternionD.GetAngle(q2Pi, qPi))); }
public void CreateRotationException2() { QuaternionD.CreateRotation(Vector3D.UnitY, Vector3D.Zero); }
public void CreateRotationException1() { QuaternionD.CreateRotation(Vector3D.Zero, Vector3D.UnitX); }
public void CreateRotation() { QuaternionD q; // From matrix vs. from angle/axis Matrix33D m = Matrix33D.CreateRotation(Vector3D.UnitX, (double)Math.PI / 4); q = QuaternionD.CreateRotation(m); QuaternionD q2 = QuaternionD.CreateRotation(Vector3D.UnitX, (double)Math.PI / 4); Assert.IsTrue(QuaternionD.AreNumericallyEqual(q2, q)); m = Matrix33D.CreateRotation(Vector3D.UnitY, (double)Math.PI / 4); q = QuaternionD.CreateRotation(m); q2 = QuaternionD.CreateRotation(Vector3D.UnitY, (double)Math.PI / 4); Assert.IsTrue(QuaternionD.AreNumericallyEqual(q2, q)); m = Matrix33D.CreateRotation(Vector3D.UnitZ, (double)Math.PI / 4); q = QuaternionD.CreateRotation(m); q2 = QuaternionD.CreateRotation(Vector3D.UnitZ, (double)Math.PI / 4); Assert.IsTrue(QuaternionD.AreNumericallyEqual(q2, q)); // From vector-vector Vector3D start, end; start = Vector3D.UnitX; end = Vector3D.UnitY; q = QuaternionD.CreateRotation(start, end); Assert.IsTrue(Vector3D.AreNumericallyEqual(end, q.ToRotationMatrix33() * start)); start = Vector3D.UnitY; end = Vector3D.UnitZ; q = QuaternionD.CreateRotation(start, end); Assert.IsTrue(Vector3D.AreNumericallyEqual(end, q.ToRotationMatrix33() * start)); start = Vector3D.UnitZ; end = Vector3D.UnitX; q = QuaternionD.CreateRotation(start, end); Assert.IsTrue(Vector3D.AreNumericallyEqual(end, q.ToRotationMatrix33() * start)); start = new Vector3D(1, 1, 1); end = new Vector3D(1, 1, 1); q = QuaternionD.CreateRotation(start, end); Assert.IsTrue(Vector3D.AreNumericallyEqual(end, q.ToRotationMatrix33() * start)); start = new Vector3D(1.0, 1.0, 1.0); end = new Vector3D(-1.0, -1.0, -1.0); q = QuaternionD.CreateRotation(start, end); Assert.IsTrue(Vector3D.AreNumericallyEqual(end, q.ToRotationMatrix33() * start)); start = new Vector3D(-1.0, 2.0, 1.0); end = new Vector3D(-2.0, -1.0, -1.0); q = QuaternionD.CreateRotation(start, end); Assert.IsTrue(Vector3D.AreNumericallyEqual(end, q.ToRotationMatrix33() * start)); double degree45 = MathHelper.ToRadians(45); q = QuaternionD.CreateRotation(degree45, Vector3D.UnitZ, degree45, Vector3D.UnitY, degree45, Vector3D.UnitX, false); QuaternionD expected = QuaternionD.CreateRotation(Vector3D.UnitZ, degree45) * QuaternionD.CreateRotation(Vector3D.UnitY, degree45) * QuaternionD.CreateRotation(Vector3D.UnitX, degree45); Assert.IsTrue(QuaternionD.AreNumericallyEqual(expected, q)); q = QuaternionD.CreateRotation(degree45, Vector3D.UnitZ, degree45, Vector3D.UnitY, degree45, Vector3D.UnitX, true); expected = QuaternionD.CreateRotation(Vector3D.UnitX, degree45) * QuaternionD.CreateRotation(Vector3D.UnitY, degree45) * QuaternionD.CreateRotation(Vector3D.UnitZ, degree45); Assert.IsTrue(QuaternionD.AreNumericallyEqual(expected, q)); }