/// <summary>
        /// Creates a quaternionr from the Euler rotations specified
        /// </summary>
        /// <param name="quaternion"></param>
        /// <param name="x">X rotation in radians</param>
        /// <param name="y">Y rotation in radians</param>
        /// <param name="z">Z rotation in radians</param>
        /// <param name="order"></param>
        /// <returns></returns>
        public static float[] QuaternionFromEuler(this float[] euler, EulerOrder order)
        {
            // http://www.mathworks.com/matlabcentral/fileexchange/
            //  20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
            //	content/SpinCalc.m

            var c1 = (float)Math.Cos(euler[0] / 2);
            var c2 = (float)Math.Cos(euler[1] / 2);
            var c3 = (float)Math.Cos(euler[2] / 2);
            var s1 = (float)Math.Sin(euler[0] / 2);
            var s2 = (float)Math.Sin(euler[1] / 2);
            var s3 = (float)Math.Sin(euler[2] / 2);

            var result = new float[4];

            if (order == EulerOrder.XYZ)
            {
                result[0] = s1 * c2 * c3 + c1 * s2 * s3;
                result[1] = c1 * s2 * c3 - s1 * c2 * s3;
                result[2] = c1 * c2 * s3 + s1 * s2 * c3;
                result[3] = c1 * c2 * c3 - s1 * s2 * s3;
            }
            else if (order == EulerOrder.YXZ)
            {
                result[0] = s1 * c2 * c3 + c1 * s2 * s3;
                result[1] = c1 * s2 * c3 - s1 * c2 * s3;
                result[2] = c1 * c2 * s3 - s1 * s2 * c3;
                result[3] = c1 * c2 * c3 + s1 * s2 * s3;
            }
            else if (order == EulerOrder.ZXY)
            {
                result[0] = s1 * c2 * c3 - c1 * s2 * s3;
                result[1] = c1 * s2 * c3 + s1 * c2 * s3;
                result[2] = c1 * c2 * s3 + s1 * s2 * c3;
                result[3] = c1 * c2 * c3 - s1 * s2 * s3;
            }
            else if (order == EulerOrder.ZYX)
            {
                result[0] = s1 * c2 * c3 - c1 * s2 * s3;
                result[1] = c1 * s2 * c3 + s1 * c2 * s3;
                result[2] = c1 * c2 * s3 - s1 * s2 * c3;
                result[3] = c1 * c2 * c3 + s1 * s2 * s3;
            }
            else if (order == EulerOrder.YZX)
            {
                result[0] = s1 * c2 * c3 + c1 * s2 * s3;
                result[1] = c1 * s2 * c3 + s1 * c2 * s3;
                result[2] = c1 * c2 * s3 - s1 * s2 * c3;
                result[3] = c1 * c2 * c3 - s1 * s2 * s3;
            }
            else if (order == EulerOrder.XZY)
            {
                result[0] = s1 * c2 * c3 - c1 * s2 * s3;
                result[1] = c1 * s2 * c3 - s1 * c2 * s3;
                result[2] = c1 * c2 * s3 + s1 * s2 * c3;
                result[3] = c1 * c2 * c3 + s1 * s2 * s3;
            }

            return(result);
        }
Exemple #2
0
 public static void GetEulerAngles(ref Matrix matrix, EulerOrder order, RotationDirection rotation, Handedness handedness, ref Vector3D eulerAngles)
 {
     GetEulerAngles(ref matrix, (long)order, (long)rotation, (long)handedness, ref eulerAngles);
     eulerAngles.x *= Mathf.Rad2Deg;
     eulerAngles.y *= Mathf.Rad2Deg;
     eulerAngles.z *= Mathf.Rad2Deg;
 }
        public static Vector3 switchAxis(Vector3 r, EulerOrder order)
        {
            switch (order)
            {
            case EulerOrder.XYZ:
                return(new Vector3(r.x, r.y, r.z));

            case EulerOrder.XZY:
                return(new Vector3(r.x, r.z, r.y));

            case EulerOrder.YXZ:
                return(new Vector3(r.y, r.x, r.z));

            case EulerOrder.YZX:
                return(new Vector3(r.y, r.z, r.x));

            case EulerOrder.ZXY:
                return(new Vector3(r.z, r.x, r.y));

            case EulerOrder.ZYX:
                return(new Vector3(r.z, r.y, r.x));

            default:
                return(r);
            }
        }
Exemple #4
0
 public Coordinate(Coordinate c)
 {
     up        = c.up;
     forward   = c.forward;
     right     = c.right;
     origin    = c.origin;
     originPos = c.originPos;
     order     = c.order;
 }
Exemple #5
0
        public void Rotate(float x, float y, float z, EulerOrder order = EulerOrder.XYZ)
        {
            double dx = x * Math.PI / 180f;
            double dy = y * Math.PI / 180f;
            double dz = z * Math.PI / 180f;

            float
                sinA = (float)Math.Sin(dx),
                cosA = (float)Math.Cos(dx),
                sinB = (float)Math.Sin(dy),
                cosB = (float)Math.Cos(dy),
                sinC = (float)Math.Sin(dz),
                cosC = (float)Math.Cos(dz);

            float m2a1, m2b1, m2c1,
                  m2a2, m2b2, m2c2,
                  m2a3, m2b3, m2c3;

            switch (order)
            {
            default:
            case EulerOrder.XYZ:
                m2a1 = cosB * cosC;
                m2b1 = -cosB * sinC;
                m2c1 = sinB;

                m2a2 = cosC * sinA * sinB + cosA * sinC;
                m2b2 = -sinC * sinB * sinA + cosC * cosA;
                m2c2 = -cosB * sinA;

                m2a3 = -cosC * sinB * cosA + sinC * sinA;
                m2b3 = cosC * sinA + sinC * sinB * cosA;
                m2c3 = cosB * cosA;
                break;

            case EulerOrder.ZYX:
                m2a1 = cosC * cosB;
                m2b1 = -sinC * cosA + cosC * sinB * sinA;
                m2c1 = sinC * sinA + cosC * sinB * cosA;

                m2a2 = sinC * cosB;
                m2b2 = cosC * cosA + sinC * sinB * sinA;
                m2c2 = -cosC * sinA + sinC * sinB * cosA;

                m2a3 = -sinB;
                m2b3 = cosB * sinA;
                m2c3 = cosB * cosA;
                break;

            case EulerOrder.XZY:
            case EulerOrder.YXZ:
            case EulerOrder.YZX:
            case EulerOrder.ZXY:
                throw new NotSupportedException("Specified euler order is not supported yet.");
            }

            float a1 = this.a1 * m2a1 + this.b1 * m2a2 + this.c1 * m2a3;
            float b1 = this.a1 * m2b1 + this.b1 * m2b2 + this.c1 * m2b3;
            float c1 = this.a1 * m2c1 + this.b1 * m2c2 + this.c1 * m2c3;

            float a2 = this.a2 * m2a1 + this.b2 * m2a2 + this.c2 * m2a3;
            float b2 = this.a2 * m2b1 + this.b2 * m2b2 + this.c2 * m2b3;
            float c2 = this.a2 * m2c1 + this.b2 * m2c2 + this.c2 * m2c3;

            float a3 = this.a3 * m2a1 + this.b3 * m2a2 + this.c3 * m2a3;
            float b3 = this.a3 * m2b1 + this.b3 * m2b2 + this.c3 * m2b3;
            float c3 = this.a3 * m2c1 + this.b3 * m2c2 + this.c3 * m2c3;

            float a4 = this.a4 * m2a1 + this.b4 * m2a2 + this.c4 * m2a3;
            float b4 = this.a4 * m2b1 + this.b4 * m2b2 + this.c4 * m2b3;
            float c4 = this.a4 * m2c1 + this.b4 * m2c2 + this.c4 * m2c3;

            this.a1 = a1; this.b1 = b1; this.c1 = c1;
            this.a2 = a2; this.b2 = b2; this.c2 = c2;
            this.a3 = a3; this.b3 = b3; this.c3 = c3;
            this.a4 = a4; this.b4 = b4; this.c4 = c4;
        }
Exemple #6
0
 public void Rotate(Vector3 v, EulerOrder order = EulerOrder.XYZ)
 {
     this.Rotate(v.x, v.y, v.z, order);
 }
	// Query representations
    /**			
        @brief get rotation in Euler angles representation.
        Euler angles are a 3D point that represents rotation in 3D. Each variable is the angle 
        of rotation around a certain axis (x/y/z). 

        @param[in] order the order in which we get the Euler angles (ROLL_PITCH_YAW as default)
        @return 3D point containing Euler angles (RADIANS) in the given order.
    */		
	public PXCMPoint3DF32 QueryEulerAngles(EulerOrder order) {
        return PXCMRotation_QueryEulerAngles(instance, order); 
    }
 internal extern static PXCMPoint3DF32 PXCMRotation_QueryEulerAngles(IntPtr instance, EulerOrder order);
Exemple #9
0
        public static NVector3 QuaternionToEuler(Quaternion q, EulerOrder rotSeq)
        {
            NVector3 res    = _quaternion2Euler(q, rotSeq);
            var      result = new NVector3();
            float    test   = q.W * q.Z + q.X * q.Y;
            float    unit   = q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W;

            switch (rotSeq)
            {
            case EulerOrder.ZYX:
                result.X = res.X;
                result.Y = res.Y;
                result.Z = res.Z;
                break;

            case EulerOrder.ZXY:
                result.X = res.Y;
                result.Y = res.X;
                result.Z = res.Z;
                break;

            case EulerOrder.YXZ:
                result.X = res.Z;
                result.Y = res.X;
                result.Z = res.Y;
                break;

            case EulerOrder.YZX:
                result.X = res.X;
                result.Y = res.Z;
                result.Z = res.Y;
                // Handle poles
                if (test > 0.4995f * unit)
                {
                    result.X = 0.0f;
                    result.Y = 2.0f * (float)Math.Atan2(q.Y, q.Z);
                    result.Z = 90.0f * Deg2Rad;
                }
                if (test < -0.4995f * unit)
                {
                    result.X = 0.0f;
                    result.Y = -2.0f * (float)Math.Atan2(q.Y, q.Z);
                    result.Z = -90.0f * Deg2Rad;
                }
                break;

            case EulerOrder.XYZ:
                result.X = res.Z;
                result.Y = res.Y;
                result.Z = res.X;
                break;

            case EulerOrder.XZY:
                result.X = res.Y;
                result.Y = res.Z;
                result.Z = res.X;
                // Handle poles
                if (test > 0.4995f * unit)
                {
                    result.X = -90.0f * Deg2Rad;
                    result.Y = -2.0f * (float)Math.Atan2(q.Y, q.Z);
                    result.Z = 0;
                }
                if (test < -0.4995f * unit)
                {
                    result.X = 0.0f;
                    result.Y = 2.0f * (float)Math.Atan2(q.Y, q.Z);
                    result.Z = -90.0f * Deg2Rad;
                }
                break;

            default:
                return(System.Numerics.Vector3.Zero);
            }
            result.X = (result.X <= -180.0f * Deg2Rad) ? result.X + 360.0f * Deg2Rad : result.X;
            result.Y = (result.Y <= -180.0f * Deg2Rad) ? result.Y + 360.0f * Deg2Rad : result.Y;
            result.Z = (result.Z <= -180.0f * Deg2Rad) ? result.Z + 360.0f * Deg2Rad : result.Z;
            return(result);
        }
Exemple #10
0
        static NVector3 _quaternion2Euler(Quaternion q, EulerOrder rotSeq)
        {
            switch (rotSeq)
            {
            case EulerOrder.ZYX:
                return(threeaxisrot(2 * (q.X * q.Y + q.W * q.Z),
                                    q.W * q.W + q.X * q.X - q.Y * q.Y - q.Z * q.Z,
                                    -2 * (q.X * q.Z - q.W * q.Y),
                                    2 * (q.Y * q.Z + q.W * q.X),
                                    q.W * q.W - q.X * q.X - q.Y * q.Y + q.Z * q.Z));


            case EulerOrder.ZYZ:
                return(twoaxisrot(2 * (q.Y * q.Z - q.W * q.X),
                                  2 * (q.X * q.Z + q.W * q.Y),
                                  q.W * q.W - q.X * q.X - q.Y * q.Y + q.Z * q.Z,
                                  2 * (q.Y * q.Z + q.W * q.X),
                                  -2 * (q.X * q.Z - q.W * q.Y)));


            case EulerOrder.ZXY:
                return(threeaxisrot(-2 * (q.X * q.Y - q.W * q.Z),
                                    q.W * q.W - q.X * q.X + q.Y * q.Y - q.Z * q.Z,
                                    2 * (q.Y * q.Z + q.W * q.X),
                                    -2 * (q.X * q.Z - q.W * q.Y),
                                    q.W * q.W - q.X * q.X - q.Y * q.Y + q.Z * q.Z));


            case EulerOrder.ZXZ:
                return(twoaxisrot(2 * (q.X * q.Z + q.W * q.Y),
                                  -2 * (q.Y * q.Z - q.W * q.X),
                                  q.W * q.W - q.X * q.X - q.Y * q.Y + q.Z * q.Z,
                                  2 * (q.X * q.Z - q.W * q.Y),
                                  2 * (q.Y * q.Z + q.W * q.X)));


            case EulerOrder.YXZ:
                return(threeaxisrot(2 * (q.X * q.Z + q.W * q.Y),
                                    q.W * q.W - q.X * q.X - q.Y * q.Y + q.Z * q.Z,
                                    -2 * (q.Y * q.Z - q.W * q.X),
                                    2 * (q.X * q.Y + q.W * q.Z),
                                    q.W * q.W - q.X * q.X + q.Y * q.Y - q.Z * q.Z));

            case EulerOrder.YXY:
                return(twoaxisrot(2 * (q.X * q.Y - q.W * q.Z),
                                  2 * (q.Y * q.Z + q.W * q.X),
                                  q.W * q.W - q.X * q.X + q.Y * q.Y - q.Z * q.Z,
                                  2 * (q.X * q.Y + q.W * q.Z),
                                  -2 * (q.Y * q.Z - q.W * q.X)));


            case EulerOrder.YZX:
                return(threeaxisrot(-2 * (q.X * q.Z - q.W * q.Y),
                                    q.W * q.W + q.X * q.X - q.Y * q.Y - q.Z * q.Z,
                                    2 * (q.X * q.Y + q.W * q.Z),
                                    -2 * (q.Y * q.Z - q.W * q.X),
                                    q.W * q.W - q.X * q.X + q.Y * q.Y - q.Z * q.Z));


            case EulerOrder.YZY:
                return(twoaxisrot(2 * (q.Y * q.Z + q.W * q.X),
                                  -2 * (q.X * q.Y - q.W * q.Z),
                                  q.W * q.W - q.X * q.X + q.Y * q.Y - q.Z * q.Z,
                                  2 * (q.Y * q.Z - q.W * q.X),
                                  2 * (q.X * q.Y + q.W * q.Z)));


            case EulerOrder.XYZ:
                return(threeaxisrot(-2 * (q.Y * q.Z - q.W * q.X),
                                    q.W * q.W - q.X * q.X - q.Y * q.Y + q.Z * q.Z,
                                    2 * (q.X * q.Z + q.W * q.Y),
                                    -2 * (q.X * q.Y - q.W * q.Z),
                                    q.W * q.W + q.X * q.X - q.Y * q.Y - q.Z * q.Z));


            case EulerOrder.XYX:
                return(twoaxisrot(2 * (q.X * q.Y + q.W * q.Z),
                                  -2 * (q.X * q.Z - q.W * q.Y),
                                  q.W * q.W + q.X * q.X - q.Y * q.Y - q.Z * q.Z,
                                  2 * (q.X * q.Y - q.W * q.Z),
                                  2 * (q.X * q.Z + q.W * q.Y)));


            case EulerOrder.XZY:
                return(threeaxisrot(2 * (q.Y * q.Z + q.W * q.X),
                                    q.W * q.W - q.X * q.X + q.Y * q.Y - q.Z * q.Z,
                                    -2 * (q.X * q.Y - q.W * q.Z),
                                    2 * (q.X * q.Z + q.W * q.Y),
                                    q.W * q.W + q.X * q.X - q.Y * q.Y - q.Z * q.Z));


            case EulerOrder.XZX:
                return(twoaxisrot(2 * (q.X * q.Z - q.W * q.Y),
                                  2 * (q.X * q.Y + q.W * q.Z),
                                  q.W * q.W + q.X * q.X - q.Y * q.Y - q.Z * q.Z,
                                  2 * (q.X * q.Z + q.W * q.Y),
                                  -2 * (q.X * q.Y - q.W * q.Z)));

            default:
                return(NVector3.Zero);
            }
        }
Exemple #11
0
    // Query representations

    /**
     *  @brief get rotation in Euler angles representation.
     *  Euler angles are a 3D point that represents rotation in 3D. Each variable is the angle
     *  of rotation around a certain axis (x/y/z).
     *
     *  @param[in] order the order in which we get the Euler angles (ROLL_PITCH_YAW as default)
     *  @return 3D point containing Euler angles (RADIANS) in the given order.
     */
    public PXCMPoint3DF32 QueryEulerAngles(EulerOrder order)
    {
        return(PXCMRotation_QueryEulerAngles(instance, order));
    }
Exemple #12
0
        public static float[] EulerFromMatrix(this float[] matrix, EulerOrder order)
        {
            var result = new float[] { 0, 0, 0 };
            // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
            var m11 = matrix[0]; var m12 = matrix[4]; var m13 = matrix[8];
            var m21 = matrix[1]; var m22 = matrix[5]; var m23 = matrix[9];
            var m31 = matrix[2]; var m32 = matrix[6]; var m33 = matrix[10];

            if (order == EulerOrder.XYZ)
            {
                result[1] = (float)Math.Asin(m13.Clamp(-1, 1));

                if (Math.Abs(m13) < 0.99999)
                {
                    result[0] = (float)Math.Atan2(-m23, m33);
                    result[2] = (float)Math.Atan2(-m12, m11);
                }
                else
                {
                    result[0] = (float)Math.Atan2(m32, m22);
                    result[2] = 0;
                }
            }
            else if (order == EulerOrder.YXZ)
            {
                result[0] = (float)Math.Asin(-(m23.Clamp(-1, 1)));

                if (Math.Abs(m23) < 0.99999)
                {
                    result[1] = (float)Math.Atan2(m13, m33);
                    result[2] = (float)Math.Atan2(m21, m22);
                }
                else
                {
                    result[1] = (float)Math.Atan2(-m31, m11);
                    result[2] = 0;
                }
            }
            else if (order == EulerOrder.ZXY)
            {
                result[0] = (float)Math.Asin(m32.Clamp(-1, 1));

                if (Math.Abs(m32) < 0.99999)
                {
                    result[1] = (float)Math.Atan2(-m31, m33);
                    result[2] = (float)Math.Atan2(-m12, m22);
                }
                else
                {
                    result[1] = 0;
                    result[2] = (float)Math.Atan2(m21, m11);
                }
            }
            else if (order == EulerOrder.ZYX)
            {
                result[1] = (float)Math.Asin(-(m31.Clamp(-1, 1)));

                if (Math.Abs(m31) < 0.99999)
                {
                    result[0] = (float)Math.Atan2(m32, m33);
                    result[2] = (float)Math.Atan2(m21, m11);
                }
                else
                {
                    result[0] = 0;
                    result[2] = (float)Math.Atan2(-m12, m22);
                }
            }
            else if (order == EulerOrder.YZX)
            {
                result[2] = (float)Math.Asin(m21.Clamp(-1, 1));

                if (Math.Abs(m21) < 0.99999)
                {
                    result[0] = (float)Math.Atan2(-m23, m22);
                    result[1] = (float)Math.Atan2(-m31, m11);
                }
                else
                {
                    result[0] = 0;
                    result[1] = (float)Math.Atan2(m13, m33);
                }
            }
            else if (order == EulerOrder.XZY)
            {
                result[2] = (float)Math.Asin(-(m12.Clamp(-1, 1)));

                if (Math.Abs(m12) < 0.99999)
                {
                    result[0] = (float)Math.Atan2(m32, m22);
                    result[1] = (float)Math.Atan2(m13, m11);
                }
                else
                {
                    result[0] = (float)Math.Atan2(-m23, m33);
                    result[1] = 0;
                }
            }

            return(result);
        }
Exemple #13
0
        public static float[] EulerFromQuaternion(this float[] quaternion, EulerOrder order)
        {
            var matrix = quaternion.MatrixFromQuaternion();

            return(matrix.EulerFromMatrix(order));
        }
Exemple #14
0
        public static float[] MatrixFromEuler(this float[] euler, EulerOrder order)
        {
            var result = new float[16];

            var x = euler[0];
            var y = euler[1];
            var z = euler[2];
            var a = (float)Math.Cos(x);
            var b = (float)Math.Sin(x);
            var c = (float)Math.Cos(y);
            var d = (float)Math.Sin(y);
            var e = (float)Math.Cos(z);
            var f = (float)Math.Sin(z);

            if (order == EulerOrder.XYZ)
            {
                var ae = a * e;
                var af = a * f;
                var be = b * e;
                var bf = b * f;

                result[0] = c * e;
                result[4] = -c * f;
                result[8] = d;

                result[1] = af + be * d;
                result[5] = ae - bf * d;
                result[9] = -b * c;

                result[2]  = bf - ae * d;
                result[6]  = be + af * d;
                result[10] = a * c;
            }
            else if (order == EulerOrder.YXZ)
            {
                var ce = c * e;
                var cf = c * f;
                var de = d * e;
                var df = d * f;

                result[0] = ce + df * b;
                result[4] = de * b - cf;
                result[8] = a * d;

                result[1] = a * f;
                result[5] = a * e;
                result[9] = -b;

                result[2]  = cf * b - de;
                result[6]  = df + ce * b;
                result[10] = a * c;
            }
            else if (order == EulerOrder.ZXY)
            {
                var ce = c * e;
                var cf = c * f;
                var de = d * e;
                var df = d * f;

                result[0] = ce - df * b;
                result[4] = -a * f;
                result[8] = de + cf * b;

                result[1] = cf + de * b;
                result[5] = a * e;
                result[9] = df - ce * b;

                result[2]  = -a * d;
                result[6]  = b;
                result[10] = a * c;
            }
            else if (order == EulerOrder.ZYX)
            {
                var ae = a * e;
                var af = a * f;
                var be = b * e;
                var bf = b * f;

                result[0] = c * e;
                result[4] = be * d - af;
                result[8] = ae * d + bf;

                result[1] = c * f;
                result[5] = bf * d + ae;
                result[9] = af * d - be;

                result[2]  = -d;
                result[6]  = b * c;
                result[10] = a * c;
            }
            else if (order == EulerOrder.YZX)
            {
                var ac = a * c;
                var ad = a * d;
                var bc = b * c;
                var bd = b * d;

                result[0] = c * e;
                result[4] = bd - ac * f;
                result[8] = bc * f + ad;

                result[1] = f;
                result[5] = a * e;
                result[9] = -b * e;

                result[2]  = -d * e;
                result[6]  = ad * f + bc;
                result[10] = ac - bd * f;
            }
            else if (order == EulerOrder.XZY)
            {
                var ac = a * c;
                var ad = a * d;
                var bc = b * c;
                var bd = b * d;

                result[0] = c * e;
                result[4] = -f;
                result[8] = d * e;

                result[1] = ac * f + bd;
                result[5] = a * e;
                result[9] = ad * f - bc;

                result[2]  = bc * f - ad;
                result[6]  = b * e;
                result[10] = bd * f + ac;
            }

            // last column
            result[3]  = 0;
            result[7]  = 0;
            result[11] = 0;

            // bottom row
            result[12] = 0;
            result[13] = 0;
            result[14] = 0;
            result[15] = 1;

            return(result);
        }
Exemple #15
0
 internal extern static PXCMPoint3DF32 PXCMRotation_QueryEulerAngles(IntPtr instance, EulerOrder order);