// Transforms euler orders back and forth between all rotation orders
    // to make sure the conversions result in the same rotation
    IEnumerator RunRotationTests(List <AxisSet> orders)
    {
        int issues = 0;

        foreach (var o1 in orders)
        {
            foreach (var o2 in orders)
            {
                EulerAngles e    = GetRandomAngles();
                EulerAngles to   = Conversions.ConvertEulerOrder(o1, o2, e);
                EulerAngles back = Conversions.ConvertEulerOrder(o2, o1, to);

                // Check if the rotations are the same or if the rotations
                // have the equivalent effect on transforming vectors
                bool equal = AreRotationsEquivalent(o1, e, back);

                if (!equal)
                {
                    Debug.LogError("Error converting " + o1.ToString(true) + " > " + o2.ToString(true));
                    Debug.Log(e.ToString("0.00000") + " > " + to.ToString("0.00000") + " > " + back.ToString("0.00000"));

                    AreRotationsEquivalent(o1, e, back, true);

                    issues++;
                }
            }
            yield return(null);
        }

        Debug.Log("Ran into " + issues + " issues when doing rotation conversions");
    }
    // Run back and forth conversion tests against a sampling of
    // coordinate frames
    IEnumerator RunCoordinateFrameTests(List <CoordinateFrame> candidateFrames, int framesToTest)
    {
        framesToTest = Mathf.Min(candidateFrames.Count, framesToTest);

        List <CoordinateFrame> remainingFrames = new List <CoordinateFrame>(candidateFrames);
        List <CoordinateFrame> frames          = new List <CoordinateFrame>();

        for (int i = 0; i < framesToTest; i++)
        {
            int index = Mathf.FloorToInt(Random.value * (remainingFrames.Count)) % remainingFrames.Count;
            frames.Add(remainingFrames[index]);
            remainingFrames.RemoveAt(index);
        }

        int issues = 0;

        foreach (var fr1 in frames)
        {
            foreach (var fr2 in frames)
            {
                // Verify that the inverse frames work as expected
                var cfc = new CoordinateFrameConverter(fr1, fr2);
                if (cfc != cfc.inverse.inverse || cfc.from != cfc.inverse.to || cfc.to != cfc.inverse.from)
                {
                    issues++;
                }

                // Position Tests
                Vector3 v    = new Vector3(1, 2, 3);
                Vector3 to   = fr1.ConvertPosition(fr2, v);
                Vector3 back = fr2.ConvertPosition(fr1, to);

                if (!AreVectorsEquivalent(v, back))
                {
                    issues++;
                }

                to   = cfc.ConvertPosition(v);
                back = cfc.inverse.ConvertPosition(to);

                if (!AreVectorsEquivalent(v, back))
                {
                    issues++;
                }

                // Rotation Conversions
                EulerAngles e     = GetRandomAngles();
                EulerAngles eTo   = Conversions.ConvertEulerAngles(fr1, fr2, e);
                EulerAngles eBack = Conversions.ConvertEulerAngles(fr2, fr1, eTo);

                bool equal = AreRotationsEquivalent(fr1.Axes, fr1.RotationOrder, e, eBack);

                if (!equal)
                {
                    Debug.LogError("Error converting " + fr1.ToString(true) + " > " + fr2.ToString(true));
                    Debug.Log(e.ToString("0.00000") + " > " + eTo.ToString("0.00000") + " > " + eBack.ToString("0.00000"));
                    AreRotationsEquivalent(fr1.Axes, fr1.RotationOrder, e, eBack, true);

                    issues++;
                }
            }

            yield return(null);
        }

        Debug.Log("Ran into " + issues + " issues when doing coordinate frame conversions");
    }