Пример #1
0
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var mat = (Matrix4d)value;

            writer.WriteStartObject();

            writer.WriteStartArray();

            writer.WritePropertyName("rotation");
            writer.WriteValue(Matrix3d.CreateFromQuaternion(mat.ExtractRotation()));
            writer.WritePropertyName("position");
            writer.WriteValue(mat.ExtractTranslation());

            writer.WriteEndObject();
        }
Пример #2
0
        /// <summary>
        /// Convert a Quaternion to all possible ways it can be represented as Euler Angles.
        /// Returns the angles in [-180, 180] space in degrees.
        /// </summary>
        public static List <Vector3> ToEulerAnglesRobust(this Quaterniond quat, string rotationOrder)
        {
            var representations = new List <Vector3>();

            var qx = quat.X;
            var qy = quat.Y;
            var qz = quat.Z;
            var qw = quat.W;

            var mat = Matrix3d.CreateFromQuaternion(quat).Inverted();

            double x, y, z;

            switch (rotationOrder)
            {
            case "ZYX":
                y = Math.Asin(-Math.Min(1, Math.Max(-1, mat.M31)));
                if (Math.Abs(mat.M31) < 0.999999)
                {
                    x = Math.Atan2(mat.M32, mat.M33);
                    z = Math.Atan2(mat.M21, mat.M11);
                }
                else
                {
                    x = Math.Atan2(-mat.M12, mat.M22);
                    z = 0f;
                }
                representations.Add(new Vector3(
                                        WMath.RadiansToDegrees((float)x),
                                        WMath.RadiansToDegrees((float)y),
                                        WMath.RadiansToDegrees((float)z)
                                        ));

                y = CopySign(Math.PI, y) - y;
                x = x - CopySign(Math.PI, x);
                z = z - CopySign(Math.PI, z);
                representations.Add(new Vector3(
                                        WMath.RadiansToDegrees((float)x),
                                        WMath.RadiansToDegrees((float)y),
                                        WMath.RadiansToDegrees((float)z)
                                        ));
                break;

            case "YXZ":
                x = Math.Asin(-Math.Min(1, Math.Max(-1, mat.M23)));
                if (Math.Abs(mat.M23) < 0.999999)
                {
                    y = Math.Atan2(mat.M13, mat.M33);
                    z = Math.Atan2(mat.M21, mat.M22);
                }
                else
                {
                    y = Math.Atan2(-mat.M31, mat.M11);
                    z = 0f;
                }
                representations.Add(new Vector3(
                                        WMath.RadiansToDegrees((float)x),
                                        WMath.RadiansToDegrees((float)y),
                                        WMath.RadiansToDegrees((float)z)
                                        ));

                x = CopySign(Math.PI, x) - x;
                y = y - CopySign(Math.PI, y);
                z = z - CopySign(Math.PI, z);
                representations.Add(new Vector3(
                                        WMath.RadiansToDegrees((float)x),
                                        WMath.RadiansToDegrees((float)y),
                                        WMath.RadiansToDegrees((float)z)
                                        ));
                break;

            default:
                throw new NotImplementedException($"Quaternion to euler rotation conversion not implemented for rotation order: {rotationOrder}");
            }

            return(representations);
        }