Пример #1
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)
                       ));
        }
Пример #2
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);
        }