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");
        }
Beispiel #2
0
        public static void AngleLessOrEqual(Quaternion a, Quaternion b, double radians)
        {
            var angle = VectorsUtils.GetAngle(a, b);

            Assert.LessOrEqual(angle, radians, "Angle");
        }
Beispiel #3
0
        public static void AngleLessOrEqual(Vector3 a, Vector3 b, double radians)
        {
            var angle = VectorsUtils.GetAngle(a, b);

            Assert.LessOrEqual(angle, radians, "Angle");
        }