user28782417
user28782417

Reputation: 1

C# SharpDX, Quaternion Squad not continue

I'm using SharpDX to perform Squad interpolation of quaternions, but the calculated results are not continuous. Here is the code. What is the issue, and how can I fix it? The following graph represents the change in the Y component (Vector3.Y) after converting quaternions to Euler angles, showing the rotation around the Y-axis. The graph displays the difference [i].Y - [i-1].Y for each samples graph here

using SharpDX;        
        private void PerformSquadOperation()
        {
            Quaternion q0 = new Quaternion(0, 0, 0, 1);
            Quaternion q1 = new Quaternion(0.016118152f, -0.00038984258f, -0.007754744f, 0.9998398f);
            Quaternion q2 = new Quaternion(0.03223115f, -0.0007795604f, -0.015507007f, 0.9993598f);
            Quaternion q3 = new Quaternion(0.032017402f, 0.0037394506f, -0.1552901f, 0.9873428f);
            Quaternion q4 = new Quaternion(0.03117278f, 0.008184779f, -0.29201335f, 0.95587116f);

            int samples = 1000;
            List<(Quaternion pos, double tValue, Vector3 Eular)> q0q1 = new();
            Quaternion[] q0q1Aux = Quaternion.SquadSetup(q0, q0, q1, q2);
            for (int i = 0; i < samples +1; i++)
            {
                float t = (float)i / samples;
                Quaternion current = Quaternion.Squad(q0, q0q1Aux[0], q0q1Aux[1], q0q1Aux[2], t);
                Vector3 currentEular = Quaternion2Eular(current);
                q0q1.Add((current, t, currentEular));
            }
            List<(Quaternion pos, double tValue, Vector3 Eular)> q1q2 = new();
            Quaternion[] q1q2Aux = Quaternion.SquadSetup(q0, q1, q2, q3);
            for (int i = 0; i < samples + 1; i++)
            {
                float t = (float)i / samples;
                Quaternion current = Quaternion.Squad(q1, q1q2Aux[0], q1q2Aux[1], q1q2Aux[2], t);
                Vector3 currentEular = Quaternion2Eular(current);
                q1q2.Add((current, t, currentEular));
            }
            List<(Quaternion pos, double tValue, Vector3 Eular)> q2q3 = new();
            Quaternion[] q2q3Aux = Quaternion.SquadSetup(q1, q2, q3, q4);
            for (int i = 0; i < samples + 1; i++)
            {
                float t = (float)i / samples;
                Quaternion current = Quaternion.Squad(q2, q2q3Aux[0], q2q3Aux[1], q2q3Aux[2], t);
                Vector3 currentEular = Quaternion2Eular(current);
                q2q3.Add((current, t, currentEular));
            }
            List<(Quaternion pos, double tValue, Vector3 Eular)> q3q4 = new();
            Quaternion[] q3q4Aux = Quaternion.SquadSetup(q2, q3, q4, q4);
            for (int i = 0; i < samples + 1; i++)
            {
                float t = (float)i / samples;
                Quaternion current = Quaternion.Squad(q3, q3q4Aux[0], q3q4Aux[1], q3q4Aux[2], t);
                Vector3 currentEular = Quaternion2Eular(current);
                q3q4.Add((current, t, currentEular));
            }

            List<(Quaternion pos, double tValue, Vector3 Eular)> AttPath = new();
            AttPath.AddRange(q0q1);
            q1q2.RemoveAt(0);
            AttPath.AddRange(q1q2);
            List<(Quaternion pos, double tValue, Vector3 Eular)> AttPath2 = new();
            AttPath2.AddRange(q2q3);
            q3q4.RemoveAt(0);
            AttPath2.AddRange(q3q4);

            List<(Quaternion q, double tValue, Vector3 Eular)> totalAttPath = new();
            totalAttPath.AddRange(AttPath);
            AttPath2.RemoveAt(0);
            totalAttPath.AddRange(AttPath2);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="q"></param>
        /// <returns>X=A,Y=B,Z=C</returns>
        public static Vector3 Quaternion2Eular(Quaternion q)
        {
            Vector3 result = new();
            q = Quaternion.Normalize(q);
            float w = q.W;
            float x = q.X;
            float y = q.Y;
            float z = q.Z;
            float ARad = MathF.Atan2(2 * (w * z + x * y), 1 - 2 * (y * y + z * z));
            float BRad = MathF.Asin(2 * (w * y - z * x));
            float CRad = MathF.Atan2(2 * (w * x + y * z), 1 - 2 * (x * x + y * y));
            result.X = (float)Rad2Deg(ARad);
            result.Y = (float)Rad2Deg(BRad);
            result.Z = (float)Rad2Deg(CRad);

            return result;
        }

        public static double Rad2Deg(double rad)
        {
            double degree = rad * 180 / System.Math.PI;
            return degree;
        }

What is the issue, and how can I fix it?

Upvotes: 0

Views: 38

Answers (0)

Related Questions