30 using System.Collections.Generic;
32 using System.Runtime.InteropServices;
33 using System.ComponentModel;
34 using System.Globalization;
35 using SiliconStudio.Core.Serialization;
37 namespace SiliconStudio.Core.Mathematics
42 [DataContract(
"quaternion")]
44 [StructLayout(LayoutKind.Sequential, Pack = 4)]
50 public static readonly
int SizeInBytes = Marshal.SizeOf(typeof(
Quaternion));
162 throw new ArgumentNullException(
"values");
163 if (values.Length != 4)
164 throw new ArgumentOutOfRangeException(
"values",
"There must be four and only four input values for Quaternion.");
178 public bool IsIdentity
180 get {
return this.Equals(Identity); }
186 public bool IsNormalized
199 float length = (X * X) + (Y * Y) + (Z * Z);
203 return (
float)(2.0 * Math.Acos(W));
215 float length = (X * X) + (Y * Y) + (Z * Z);
217 return Vector3.UnitX;
219 float inv = 1.0f / length;
220 return new Vector3(X * inv, Y * inv, Z * inv);
231 public float this[
int index]
243 throw new ArgumentOutOfRangeException(
"index",
"Indices for Quaternion run from 0 to 3, inclusive.");
250 case 0: X = value;
break;
251 case 1: Y = value;
break;
252 case 2: Z = value;
break;
253 case 3: W = value;
break;
254 default:
throw new ArgumentOutOfRangeException(
"index",
"Indices for Quaternion run from 0 to 3, inclusive.");
274 float lengthSq = LengthSquared();
277 lengthSq = 1.0f / lengthSq;
296 return (
float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W));
309 return (X * X) + (Y * Y) + (Z * Z) + (W * W);
317 float length = Length();
320 float inverse = 1.0f / length;
334 return new float[] { X, Y, Z, W };
345 result.X = left.X + right.X;
346 result.Y = left.Y + right.Y;
347 result.Z = left.Z + right.Z;
348 result.W = left.W + right.W;
360 Add(ref left, ref right, out result);
372 result.X = left.X - right.X;
373 result.Y = left.Y - right.Y;
374 result.Z = left.Z - right.Z;
375 result.W = left.W - right.W;
387 Subtract(ref left, ref right, out result);
399 result.X = value.X * scale;
400 result.Y = value.Y * scale;
401 result.Z = value.Z * scale;
402 result.W = value.W * scale;
414 Multiply(ref value, scale, out result);
435 result.X = (rx * lw + lx * rw + ry * lz) - (rz * ly);
436 result.Y = (ry * lw + ly * rw + rz * lx) - (rx * lz);
437 result.Z = (rz * lw + lz * rw + rx * ly) - (ry * lx);
438 result.W = (rw * lw) - (rx * lx + ry * ly + rz * lz);
450 Multiply(ref left, ref right, out result);
475 Negate(ref value, out result);
491 Slerp(ref value1, ref value2, amount1 + amount2, out start);
492 Slerp(ref value1, ref value3, amount1 + amount2, out end);
493 Slerp(ref start, ref end, amount2 / (amount1 + amount2), out result);
508 Barycentric(ref value1, ref value2, ref value3, amount1, amount2, out result);
533 Conjugate(ref value, out result);
545 result = (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z) + (left.W * right.W);
556 return (left.
X * right.
X) + (left.Y * right.Y) + (left.
Z * right.
Z) + (left.W * right.W);
566 float angle = (float)Math.Sqrt((value.X * value.X) + (value.Y * value.Y) + (value.Z * value.Z));
567 float sin = (float)Math.Sin(angle);
569 if (Math.Abs(sin) >= MathUtil.ZeroTolerance)
571 float coeff = sin / angle;
572 result.X = coeff * value.X;
573 result.Y = coeff * value.Y;
574 result.Z = coeff * value.Z;
581 result.W = (float)Math.Cos(angle);
592 Exponential(ref value, out result);
615 Invert(ref value, out result);
633 float inverse = 1.0f - amount;
635 if (Dot(start, end) >= 0.0f)
637 result.X = (inverse * start.X) + (amount * end.X);
638 result.Y = (inverse * start.Y) + (amount * end.Y);
639 result.Z = (inverse * start.Z) + (amount * end.Z);
640 result.W = (inverse * start.W) + (amount * end.W);
644 result.X = (inverse * start.X) - (amount * end.X);
645 result.Y = (inverse * start.Y) - (amount * end.Y);
646 result.Z = (inverse * start.Z) - (amount * end.Z);
647 result.W = (inverse * start.W) - (amount * end.W);
668 Lerp(ref start, ref end, amount, out result);
679 if (Math.Abs(value.W) < 1.0)
681 float angle = (float)Math.Acos(value.W);
682 float sin = (float)Math.Sin(angle);
684 if (Math.Abs(sin) >= MathUtil.ZeroTolerance)
686 float coeff = angle / sin;
687 result.X = value.X * coeff;
688 result.Y = value.Y * coeff;
689 result.Z = value.Z * coeff;
712 Logarithm(ref value, out result);
748 Vector3.Normalize(ref axis, out normalized);
750 float half = angle * 0.5f;
751 float sin = (float)Math.Sin(half);
752 float cos = (float)Math.Cos(half);
754 result.X = normalized.X * sin;
755 result.Y = normalized.Y * sin;
756 result.Z = normalized.Z * sin;
769 RotationAxis(ref axis, angle, out result);
782 float scale = matrix.M11 + matrix.M22 + matrix.M33;
786 sqrt = (float)Math.Sqrt(scale + 1.0f);
787 result.W = sqrt * 0.5f;
790 result.X = (matrix.M23 - matrix.M32) * sqrt;
791 result.Y = (matrix.M31 - matrix.M13) * sqrt;
792 result.Z = (matrix.M12 - matrix.M21) * sqrt;
794 else if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33))
796 sqrt = (float)Math.Sqrt(1.0f + matrix.M11 - matrix.M22 - matrix.M33);
799 result.X = 0.5f * sqrt;
800 result.Y = (matrix.M12 + matrix.M21) * half;
801 result.Z = (matrix.M13 + matrix.M31) * half;
802 result.W = (matrix.M23 - matrix.M32) * half;
804 else if (matrix.M22 > matrix.M33)
806 sqrt = (float)Math.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33);
809 result.X = (matrix.M21 + matrix.M12) * half;
810 result.Y = 0.5f * sqrt;
811 result.Z = (matrix.M32 + matrix.M23) * half;
812 result.W = (matrix.M31 - matrix.M13) * half;
816 sqrt = (float)Math.Sqrt(1.0f + matrix.M33 - matrix.M11 - matrix.M22);
819 result.X = (matrix.M31 + matrix.M13) * half;
820 result.Y = (matrix.M32 + matrix.M23) * half;
821 result.Z = 0.5f * sqrt;
822 result.W = (matrix.M12 - matrix.M21) * half;
834 RotationMatrix(ref matrix, out result);
845 float halfAngle = angle * 0.5f;
846 result =
new Quaternion((
float)Math.Sin(halfAngle), 0.0f, 0.0f, (float)Math.Cos(halfAngle));
857 RotationX(angle, out result);
868 float halfAngle = angle * 0.5f;
869 result =
new Quaternion(0.0f, (
float)Math.Sin(halfAngle), 0.0f, (float)Math.Cos(halfAngle));
880 RotationY(angle, out result);
891 float halfAngle = angle * 0.5f;
892 result =
new Quaternion(0.0f, 0.0f, (
float)Math.Sin(halfAngle), (float)Math.Cos(halfAngle));
903 RotationZ(angle, out result);
916 float halfRoll = roll * 0.5f;
917 float halfPitch = pitch * 0.5f;
918 float halfYaw = yaw * 0.5f;
920 float sinRoll = (float)Math.Sin(halfRoll);
921 float cosRoll = (float)Math.Cos(halfRoll);
922 float sinPitch = (float)Math.Sin(halfPitch);
923 float cosPitch = (float)Math.Cos(halfPitch);
924 float sinYaw = (float)Math.Sin(halfYaw);
925 float cosYaw = (float)Math.Cos(halfYaw);
927 result.X = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);
928 result.Y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);
929 result.Z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);
930 result.W = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);
943 RotationYawPitchRoll(yaw, pitch, roll, out result);
958 float dot = Dot(start, end);
960 if (Math.Abs(dot) > 1.0f - MathUtil.ZeroTolerance)
962 inverse = 1.0f - amount;
963 opposite = amount * Math.Sign(dot);
967 float acos = (float)Math.Acos(Math.Abs(dot));
968 float invSin = (float)(1.0 / Math.Sin(acos));
970 inverse = (float)Math.Sin((1.0f - amount) * acos) * invSin;
971 opposite = (float)Math.Sin(amount * acos) * invSin * Math.Sign(dot);
974 result.X = (inverse * start.X) + (opposite * end.X);
975 result.Y = (inverse * start.Y) + (opposite * end.Y);
976 result.Z = (inverse * start.Z) + (opposite * end.Z);
977 result.W = (inverse * start.W) + (opposite * end.W);
990 Slerp(ref start, ref end, amount, out result);
1006 Slerp(ref value1, ref value4, amount, out start);
1007 Slerp(ref value2, ref value3, amount, out end);
1008 Slerp(ref start, ref end, 2.0f * amount * (1.0f - amount), out result);
1023 Squad(ref value1, ref value2, ref value3, ref value4, amount, out result);
1037 Quaternion q0 = (value1 + value2).LengthSquared() < (value1 - value2).LengthSquared() ? -value1 : value1;
1038 Quaternion q2 = (value2 + value3).LengthSquared() < (value2 - value3).LengthSquared() ? -value3 : value3;
1039 Quaternion q3 = (value3 + value4).LengthSquared() < (value3 - value4).LengthSquared() ? -value4 : value4;
1043 Exponential(ref q1, out q1Exp);
1044 Exponential(ref q2, out q2Exp);
1047 results[0] = q1 * Exponential(-0.25f * (Logarithm(q1Exp * q2) + Logarithm(q1Exp * q0)));
1048 results[1] = q2 * Exponential(-0.25f * (Logarithm(q2Exp * q3) + Logarithm(q2Exp * q1)));
1063 Add(ref left, ref right, out result);
1076 Subtract(ref left, ref right, out result);
1088 Negate(ref value, out result);
1101 Multiply(ref value, scale, out result);
1114 Multiply(ref value, scale, out result);
1127 Multiply(ref left, ref right, out result);
1139 return left.Equals(right);
1150 return !left.Equals(right);
1161 return string.Format(CultureInfo.CurrentCulture,
"X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W);
1176 return string.Format(CultureInfo.CurrentCulture,
"X:{0} Y:{1} Z:{2} W:{3}", X.ToString(
format, CultureInfo.CurrentCulture),
1177 Y.ToString(format, CultureInfo.CurrentCulture), Z.ToString(
format, CultureInfo.CurrentCulture), W.ToString(format, CultureInfo.CurrentCulture));
1189 return string.Format(formatProvider,
"X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W);
1203 return ToString(formatProvider);
1205 return string.Format(formatProvider,
"X:{0} Y:{1} Z:{2} W:{3}", X.ToString(
format, formatProvider),
1206 Y.ToString(format, formatProvider), Z.ToString(
format, formatProvider), W.ToString(format, formatProvider));
1217 return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
1229 return ((
float)Math.Abs(other.
X - X) < MathUtil.ZeroTolerance &&
1230 (float)Math.Abs(other.
Y - Y) < MathUtil.ZeroTolerance &&
1231 (float)Math.Abs(other.
Z - Z) < MathUtil.ZeroTolerance &&
1232 (float)Math.Abs(other.
W - W) < MathUtil.ZeroTolerance);
1247 if (value.GetType() != GetType())
1259 public static implicit
operator SlimDX.Quaternion(
Quaternion value)
1261 return new SlimDX.Quaternion(value.X, value.Y, value.Z, value.W);
1269 public static implicit
operator Quaternion(SlimDX.Quaternion value)
1271 return new Quaternion(value.X, value.Y, value.Z, value.W);
1281 public static implicit
operator System.Windows.Media.Media3D.Quaternion(
Quaternion value)
1283 return new System.Windows.Media.Media3D.Quaternion(value.X, value.Y, value.Z, value.W);
1291 public static explicit operator Quaternion(System.Windows.Media.Media3D.Quaternion value)
1293 return new Quaternion((
float)value.X, (
float)value.Y, (
float)value.Z, (
float)value.W);
1303 public static implicit
operator Microsoft.Xna.Framework.Quaternion(
Quaternion value)
1305 return new Microsoft.Xna.Framework.Quaternion(value.X, value.Y, value.Z, value.W);
1313 public static implicit
operator Quaternion(Microsoft.Xna.Framework.Quaternion value)
1315 return new Quaternion(value.X, value.Y, value.Z, value.W);
static float Dot(Quaternion left, Quaternion right)
Calculates the dot product of two quaternions.
static void Negate(ref Quaternion value, out Quaternion result)
Reverses the direction of a given quaternion.
static void RotationY(float angle, out Quaternion result)
Creates a quaternion that rotates around the x-axis.
static Quaternion RotationMatrix(Matrix matrix)
Creates a quaternion given a rotation matrix.
FbxDouble3 operator*(double factor, FbxDouble3 vector)
void Conjugate()
Conjugates the quaternion.
string ToString(string format, IFormatProvider formatProvider)
Returns a System.String that represents this instance.
static void Squad(ref Quaternion value1, ref Quaternion value2, ref Quaternion value3, ref Quaternion value4, float amount, out Quaternion result)
Interpolates between quaternions, using spherical quadrangle interpolation.
Represents a two dimensional mathematical vector.
float Y
The Y component of the quaternion.
static void RotationAxis(ref Vector3 axis, float angle, out Quaternion result)
Creates a quaternion given a rotation and an axis.
static Quaternion RotationX(float angle)
Creates a quaternion that rotates around the x-axis.
static void Conjugate(ref Quaternion value, out Quaternion result)
Conjugates a quaternion.
Quaternion(float[] values)
Initializes a new instance of the SiliconStudio.Core.Mathematics.Quaternion struct.
static void Lerp(ref Quaternion start, ref Quaternion end, float amount, out Quaternion result)
Performs a linear interpolation between two quaternions.
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ float size_t y
static void Multiply(ref Quaternion value, float scale, out Quaternion result)
Scales a quaternion by the given value.
static void RotationYawPitchRoll(float yaw, float pitch, float roll, out Quaternion result)
Creates a quaternion given a yaw, pitch, and roll value.
static void RotationMatrix(ref Matrix matrix, out Quaternion result)
Creates a quaternion given a rotation matrix.
static Quaternion RotationAxis(Vector3 axis, float angle)
Creates a quaternion given a rotation and an axis.
static Quaternion Multiply(Quaternion left, Quaternion right)
Modulates a quaternion by another.
float X
The X component of the quaternion.
const float ZeroTolerance
The value for which all absolute numbers smaller than are considered equal to zero.
Represents a three dimensional mathematical vector.
static void Subtract(ref Quaternion left, ref Quaternion right, out Quaternion result)
Subtracts two quaternions.
static Quaternion RotationY(float angle)
Creates a quaternion that rotates around the x-axis.
static void Exponential(ref Quaternion value, out Quaternion result)
Exponentiates a quaternion.
override int GetHashCode()
Returns a hash code for this instance.
void Invert()
Conjugates and renormalizes the quaternion.
static void Multiply(ref Quaternion left, ref Quaternion right, out Quaternion result)
Modulates a quaternion by another.
bool Equals(Quaternion other)
Determines whether the specified SiliconStudio.Core.Mathematics.Quaternion is equal to this instance...
static Quaternion Conjugate(Quaternion value)
Conjugates a quaternion.
Quaternion(float x, float y, float z, float w)
Initializes a new instance of the SiliconStudio.Core.Mathematics.Quaternion struct.
static Quaternion[] SquadSetup(Quaternion value1, Quaternion value2, Quaternion value3, Quaternion value4)
Sets up control points for spherical quadrangle interpolation.
static void Slerp(ref Quaternion start, ref Quaternion end, float amount, out Quaternion result)
Interpolates between two quaternions, using spherical linear interpolation.
Quaternion(float value)
Initializes a new instance of the SiliconStudio.Core.Mathematics.Quaternion struct.
Represents a four dimensional mathematical vector.
string ToString(IFormatProvider formatProvider)
Returns a System.String that represents this instance.
Represents a four dimensional mathematical quaternion.
float LengthSquared()
Calculates the squared length of the quaternion.
static void Normalize(ref Quaternion value, out Quaternion result)
Converts the quaternion into a unit quaternion.
void Normalize()
Converts the quaternion into a unit quaternion.
static void Logarithm(ref Quaternion value, out Quaternion result)
Calculates the natural logarithm of the specified quaternion.
static Quaternion Lerp(Quaternion start, Quaternion end, float amount)
Performs a linear interpolation between two quaternion.
string ToString(string format)
Returns a System.String that represents this instance.
override string ToString()
Returns a System.String that represents this instance.
SiliconStudio.Core.Mathematics.Quaternion Quaternion
override bool Equals(object value)
Determines whether the specified System.Object is equal to this instance.
static Quaternion Subtract(Quaternion left, Quaternion right)
Subtracts two quaternions.
float Z
The Z component of the quaternion.
Quaternion(Vector2 value, float z, float w)
Initializes a new instance of the SiliconStudio.Core.Mathematics.Quaternion struct.
static Quaternion Invert(Quaternion value)
Conjugates and renormalizes the quaternion.
static void Barycentric(ref Quaternion value1, ref Quaternion value2, ref Quaternion value3, float amount1, float amount2, out Quaternion result)
Returns a SiliconStudio.Core.Mathematics.Quaternion containing the 4D Cartesian coordinates of a poin...
static void Add(ref Quaternion left, ref Quaternion right, out Quaternion result)
Adds two quaternions.
float[] ToArray()
Creates an array containing the elements of the quaternion.
static Quaternion Normalize(Quaternion value)
Converts the quaternion into a unit quaternion.
static void RotationZ(float angle, out Quaternion result)
Creates a quaternion that rotates around the x-axis.
static Quaternion Add(Quaternion left, Quaternion right)
Adds two quaternions.
Quaternion(Vector3 value, float w)
Initializes a new instance of the SiliconStudio.Core.Mathematics.Quaternion struct.
static Quaternion RotationYawPitchRoll(float yaw, float pitch, float roll)
Creates a quaternion given a yaw, pitch, and roll value.
float Length()
Calculates the length of the quaternion.
static Quaternion Exponential(Quaternion value)
Exponentiates a quaternion.
SiliconStudio.Core.Mathematics.Vector3 Vector3
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
static Quaternion RotationZ(float angle)
Creates a quaternion that rotates around the x-axis.
Quaternion(Vector4 value)
Initializes a new instance of the SiliconStudio.Core.Mathematics.Quaternion struct.
static Quaternion Squad(Quaternion value1, Quaternion value2, Quaternion value3, Quaternion value4, float amount)
Interpolates between quaternions, using spherical quadrangle interpolation.
static Quaternion Multiply(Quaternion value, float scale)
Scales a quaternion by the given value.
static void Invert(ref Quaternion value, out Quaternion result)
Conjugates and renormalizes the quaternion.
static void Dot(ref Quaternion left, ref Quaternion right, out float result)
Calculates the dot product of two quaternions.
static Quaternion Slerp(Quaternion start, Quaternion end, float amount)
Interpolates between two quaternions, using spherical linear interpolation.
static Quaternion Negate(Quaternion value)
Reverses the direction of a given quaternion.
static Quaternion Logarithm(Quaternion value)
Calculates the natural logarithm of the specified quaternion.
DataStyle
Specifies the style used for textual serialization when an array/list or a dictionary/map must be ser...
static void RotationX(float angle, out Quaternion result)
Creates a quaternion that rotates around the x-axis.
static Quaternion Barycentric(Quaternion value1, Quaternion value2, Quaternion value3, float amount1, float amount2)
Returns a SiliconStudio.Core.Mathematics.Quaternion containing the 4D Cartesian coordinates of a poin...
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ float size_t size_t z
float W
The W component of the quaternion.
Represents a 4x4 mathematical matrix.