public void TestHermiteAsSphericalInterpolation() { // given two quaternions, we must find a tangent quaternion so that the quaternion // hermite interpolation gives roughly the same results as a plain spherical interpolation. // reference implementation with matrices var m1 = Matrix4x4.CreateFromAxisAngle(Vector3.UnitX, 1); var m2 = Matrix4x4.CreateFromAxisAngle(Vector3.UnitY, 2); var mt = Matrix4x4.Multiply(m2, Matrix4x4.Transpose(m1)); var m2bis = Matrix4x4.Multiply(mt, m1); // roundtrip; M2 == M2BIS // implementation with quaternions var q1 = Quaternion.CreateFromAxisAngle(Vector3.UnitX, 1); var q2 = Quaternion.CreateFromAxisAngle(Vector3.UnitY, 2); var qt = Quaternion.Concatenate(q2, Quaternion.Conjugate(q1)); var q2bis = Quaternion.Concatenate(qt, q1); // roundtrip; Q2 == Q2BIS NumericsAssert.AreEqual(qt, Animations.SamplerFactory.CreateTangent(q1, q2), 0.000001f); var angles = new List <Vector2>(); for (float amount = 0; amount <= 1; amount += 0.025f) { // slerp interpolation var sq = Quaternion.Normalize(Quaternion.Slerp(q1, q2, amount)); // hermite interpolation with a unit tangent var hermite = Animations.SamplerFactory.CreateHermitePointWeights(amount); var hq = default(Quaternion); hq += q1 * hermite.Item1; hq += q2 * hermite.Item2; hq += qt * hermite.Item3; hq += qt * hermite.Item4; hq = Quaternion.Normalize(hq); // check NumericsAssert.AreEqual(sq, hq, 0.1f); NumericsAssert.AngleLessOrEqual(sq, hq, 0.22f); // diff var a = VectorsUtils.GetAngle(sq, hq) * 180.0f / 3.141592f; angles.Add(new Vector2(amount, a)); } angles.ToPointSeries() .WithLineType(Plotting.LineType.Continuous) .AttachToCurrentTest("plot.png"); }
public static void AngleLessOrEqual(Quaternion a, Quaternion b, double radians) { var angle = VectorsUtils.GetAngle(a, b); Assert.LessOrEqual(angle, radians, "Angle"); }
public static void AngleLessOrEqual(Vector3 a, Vector3 b, double radians) { var angle = VectorsUtils.GetAngle(a, b); Assert.LessOrEqual(angle, radians, "Angle"); }