Пример #1
0
        /// <summary>
        /// Calculates the natural logarithm of the specified quaternion
        /// </summary>
        /// <param name="value">The quaternion whose logarithm will be calculated</param>
        /// <returns>The natural logarithm of the quaternion</returns>
        public static Quaternion Logarithm(Quaternion value)
        {
            Quaternion result = new Quaternion();

            if (Mathematics.Abs(value.W) < 1f)
            {
                float angle = Mathematics.Acos(value.W);
                float sin   = Mathematics.Sin(angle);

                if (Mathematics.Abs(sin) >= 0f)
                {
                    float coeff = angle / sin;
                    result.X = value.X * coeff;
                    result.Y = value.Y * coeff;
                    result.Z = value.Z * coeff;
                }
                else
                {
                    result = value;
                }
            }
            else
            {
                result = value;
            }

            result.W = 0f;

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Interpolates between two quaternions, using spherical linear interpolation
        /// </summary>
        /// <param name="start">Start quaternion</param>
        /// <param name="end">End quaternion</param>
        /// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/></param>
        /// <returns>The spherical linear interpolation of the two quaternions</returns>
        public static Quaternion Slerp(Quaternion start, Quaternion end, float amount)
        {
            float opposite;
            float inverse;
            float dot = DotProduct(start, end);

            if (Mathematics.Abs(dot) > 1f - 0f)
            {
                inverse  = 1f - amount;
                opposite = amount * Mathematics.Sign(dot);
            }
            else
            {
                float acos   = Mathematics.Acos(Mathematics.Abs(dot));
                float invSin = (float)(1f / Mathematics.Sin(acos));

                inverse  = Mathematics.Sin((1f - amount) * acos) * invSin;
                opposite = Mathematics.Sin(amount * acos) * invSin * Mathematics.Sign(dot);
            }

            return(new Quaternion(
                       (inverse * start.X) + (opposite * end.X),
                       (inverse * start.Y) + (opposite * end.Y),
                       (inverse * start.Z) + (opposite * end.Z),
                       (inverse * start.W) + (opposite * end.W)
                       ));
        }
Пример #3
0
        /// <summary>
        /// Calculates the distance between two vectors
        /// </summary>
        /// <param name="value1">The first vector</param>
        /// <param name="value2">The second vector</param>
        /// <returns>The distance between the two vectors</returns>
        public static float Distance(Vector4 value1, Vector4 value2)
        {
            float x = value1.X - value2.X;
            float y = value1.Y - value2.Y;
            float z = value1.Z - value2.Z;
            float w = value1.W - value2.W;

            return(Mathematics.Sqrt(x * x + y * y + z * z + w * w));
        }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of the struct
        /// </summary>
        /// <param name="value">A vector containing the values with which to initialize the X, Y, and Z components</param>
        /// <param name="angle">Initial value for the angle of the quaternion</param>
        public Quaternion(Vector3 axis, float angle)
        {
            float angle2 = angle * 0.5f;
            float s      = Mathematics.Sin(angle2) / Vector3.Magnitude(axis);

            X = axis.X * s;
            Y = axis.Y * s;
            Z = axis.Z * s;
            W = Mathematics.Cos(angle2);
        }
Пример #5
0
        /// <summary>
        /// Creates a quaternion given a rotation and an axis
        /// </summary>
        /// <param name="axis">The axis of rotation</param>
        /// <param name="angle">The angle of rotation</param>
        /// <returns>The newly created quaternion</returns>
        public static Quaternion RotationAxis(Vector3 axis, float angle)
        {
            Vector3 normalized;

            normalized = Vector3.Normalize(axis);

            float half = angle * 0.5f;
            float sin  = Mathematics.Sin(half);
            float cos  = Mathematics.Cos(half);

            return(new Quaternion(normalized.X * sin, normalized.Y * sin, normalized.Z * sin, cos));
        }
Пример #6
0
        /// <summary>
        /// Creates a quaternion given a yaw, pitch, and roll value
        /// </summary>
        /// <param name="yaw">The yaw of rotation</param>
        /// <param name="pitch">The pitch of rotation</param>
        /// <param name="roll">The roll of rotation</param>
        /// <returns>The newly created quaternion</returns>
        public static Quaternion RotationYawPitchRoll(float yaw, float pitch, float roll)
        {
            float halfRoll  = roll * 0.5f;
            float halfPitch = pitch * 0.5f;
            float halfYaw   = yaw * 0.5f;

            float sinRoll  = Mathematics.Sin(halfRoll);
            float cosRoll  = Mathematics.Cos(halfRoll);
            float sinPitch = Mathematics.Sin(halfPitch);
            float cosPitch = Mathematics.Cos(halfPitch);
            float sinYaw   = Mathematics.Sin(halfYaw);
            float cosYaw   = Mathematics.Cos(halfYaw);

            return(new Quaternion(
                       (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll),
                       (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll),
                       (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll),
                       (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll)
                       ));
        }
Пример #7
0
        /// <summary>
        /// Exponentiates a quaternion
        /// </summary>
        /// <param name="value">The quaternion to exponentiate</param>
        /// <returns>The exponentiated quaternion</returns>
        public static Quaternion Exponential(Quaternion value)
        {
            Quaternion result = new Quaternion();

            float angle = Mathematics.Sqrt((value.X * value.X) + (value.Y * value.Y) + (value.Z * value.Z));
            float sin   = Mathematics.Sin(angle);

            if (Mathematics.Abs(sin) >= 0f)
            {
                float coeff = sin / angle;
                result.X = coeff * value.X;
                result.Y = coeff * value.Y;
                result.Z = coeff * value.Z;
            }
            else
            {
                result = value;
            }

            result.W = Mathematics.Cos(angle);

            return(result);
        }
Пример #8
0
 /// <summary>
 /// Calculates the length of the quaternion
 /// </summary>
 /// <returns>The length of the vector</returns>
 public static float Magnitude(Quaternion value) => Mathematics.Sqrt(Mathematics.Pow(value.X, 2)) + Mathematics.Sqrt(Mathematics.Pow(value.Y, 2)) + Mathematics.Sqrt(Mathematics.Pow(value.Z, 2)) + Mathematics.Sqrt(Mathematics.Pow(value.W, 2));
Пример #9
0
 /// <summary>
 /// Calculates the length of the vector
 /// </summary>
 /// <returns>May be preferred when only the relative length is needed and speed is of the essence</returns>
 public static float Magnitude(Vector4 value) => Mathematics.Sqrt(Mathematics.Pow(value.X, 2) + Mathematics.Pow(value.Y, 2) + Mathematics.Pow(value.Z, 2) + Mathematics.Pow(value.W, 2));
Пример #10
0
 /// <summary>
 /// Get's a value indicting whether this instance is normalized
 /// </summary>
 public bool IsNormalized() => Mathematics.Abs(X * X + Y * Y + Z * Z + W * W - 1f) < 0f;