From 527fb1936433d7911a18011f8093a5de8fd6e42a Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Fri, 13 Feb 2009 19:53:46 +0000 Subject: [PATCH] Implemented IEquatable interface. Fixed ToAxisAngle implementation at 0-degree angles. Added ToAxisAngle overload that returns a Vector4 struct. --- Source/OpenTK/Math/Quaternion.cs | 100 +++++++++++++++++++++++------- Source/OpenTK/Math/Quaterniond.cs | Bin 77476 -> 82592 bytes 2 files changed, 79 insertions(+), 21 deletions(-) diff --git a/Source/OpenTK/Math/Quaternion.cs b/Source/OpenTK/Math/Quaternion.cs index 15a9da10..eb1e31c4 100644 --- a/Source/OpenTK/Math/Quaternion.cs +++ b/Source/OpenTK/Math/Quaternion.cs @@ -32,7 +32,7 @@ namespace OpenTK.Math /// [Serializable] [StructLayout(LayoutKind.Sequential)] - public struct Quaternion + public struct Quaternion : IEquatable { #region Fields @@ -111,7 +111,7 @@ namespace OpenTK.Math #region Instance - #region pubilc void ToAxisAngle(out Vector3 axis, out float angle) + #region ToAxisAngle /// /// Convert the current quaternion to axis angle representation @@ -120,19 +120,39 @@ namespace OpenTK.Math /// The resultant angle public void ToAxisAngle(out Vector3 axis, out float angle) { - Quaternion q = this; - if (q.W > 1.0f) - q.Normalize(); - - angle = 2.0f * (float)System.Math.Acos(q.W); - float den = (float)System.Math.Sqrt(1.0 - q.W * q.W); - axis = q.XYZ; - if (den > 0.0001f) - { - axis = q.XYZ / den; - } + Vector4 result = ToAxisAngle(); + axis = result.Xyz; + angle = result.W; } + /// + /// Convert this instance to an axis-angle representation. + /// + /// A Vector4 that is the axis-angle representation of this quaternion. + public Vector4 ToAxisAngle() + { + Quaternion q = this; + if (q.W > 1.0f) + q.Normalize(); + + Vector4 result = new Vector4(); + + result.W = 2.0f * (float)System.Math.Acos(q.W); // angle + float den = (float)System.Math.Sqrt(1.0 - q.W * q.W); + if (den > 0.0001f) + { + result.Xyz = q.XYZ / den; + } + else + { + // This occurs when the angle is zero. + // Not a problem: just set an arbitrary normalized axis. + result.Xyz = Vector3.UnitX; + } + + return result; + } + #endregion #region public float Length @@ -483,18 +503,14 @@ namespace OpenTK.Math return left; } - [CLSCompliant(false)] - unsafe public static explicit operator float*(Quaternion q) + public static bool operator ==(Quaternion left, Quaternion right) { - return &q.XYZ.X; + return left.Equals(right); } - public static explicit operator IntPtr(Quaternion q) + public static bool operator !=(Quaternion left, Quaternion right) { - unsafe - { - return (IntPtr)(&q.XYZ.X); - } + return !left.Equals(right); } #endregion @@ -514,8 +530,50 @@ namespace OpenTK.Math #endregion + #region public override bool Equals (object o) + + /// + /// Compares this object instance to another object for equality. + /// + /// The other object to be used in the comparison. + /// True if both objects are Quaternions of equal value. Otherwise it returns false. + public override bool Equals(object o) + { + if (o is Quaternion == false) return false; + return this == (Quaternion)o; + } + #endregion + #region public override int GetHashCode () + + /// + /// Provides the hash code for this object. + /// + /// A hash code formed from the bitwise XOR of this objects members. + public override int GetHashCode() + { + return XYZ.GetHashCode() ^ W.GetHashCode(); + } + + #endregion + + #endregion + + #endregion + + #region IEquatable Members + + /// + /// Compares this Quaternion instance to another Quaternion for equality. + /// + /// The other Quaternion to be used in the comparison. + /// True if both instances are equal; false otherwise. + public bool Equals(Quaternion other) + { + return XYZ == other.XYZ && W == other.W; + } + #endregion } } diff --git a/Source/OpenTK/Math/Quaterniond.cs b/Source/OpenTK/Math/Quaterniond.cs index 596ff2b1c6959a295be0ad6bed550fb72041a634..0fec25d8f9ac4f28d676deafcf7ee6b76d0c55c0 100644 GIT binary patch delta 2091 zcmb7FT})eL82&yBwA510Xz359hn~ZLwgU{+I=e%8b0*;STci}+2l3>#z5LA1$T+RZAM72*y*Y`UfO+tv>% zpv~g~SNsBe=LteC-~`Fr4c|YMAQl>g=0PXi^R_MbO3SzEVQtU_t6nFBYkbSSweaY; z6`e=*6%!9bEN83kV568ki^&!+c?OfKECMYaS$8R1g>%Ce6I~=)9i|)XCTukM^@k-~ zf-hSoc&EJ$)W9jM!U-cTms>^eS@ch^8S(o%OJmd)(7YjdKhTS|R*(jy&L}>;j2W*8 z`z-6g^CFuNt*gSvIFB8SQmJD6RNfk6!>xc~;Fl!U3 zPGGtq{>xx$oX^@+*y`^Kc=cp5e&F7 zAcLAog4*nIhYORG!J>m$RvH1A0G^g%<$e%$PT2SPYy14|nkK+XVN*|v6sx5Txu14VMFl_(|=>0i#4n48a~g6NT^SC zvC!{z%9oE%KoW3^LiaNQz?AS?&>#5u`M}X^9Oh#CQp8Lvi(1)klbcXWc*=*u1fc_o z_B;dL+)_ym8mtLV)S=fDLXM+%rco67ijUXg7X7yFQbi04p2gC3 zh#hL(7X4F&*Whx0O^+&E(;q9mZ+$iU^8-lr*H{1N+lY6=@5e&4_A3u)7~X4W(BG1| zRDGmgVLq;SpQuoOQHw_^6to`A@jvufeWV`6NOk6Ah}i5M7+U2;?g`=DVH4<+w7ReY zv3k(7FzB%Ln+!WsCFZ<2Bu+m=+YDhY>!j^ZqACUpvk~?Zdl~N<@uT8f^9*s%-9Fs5bOHGc85ShF{(qM9ffZF5-5fYOVOt>bmk>r}J zCnW zDp)lqLn1>SLpnnaL+WIEdGX25qSYqX{pR8XV7G@o-9}*$(h2C3RI=QU_1F? zwC>~y^Ef86D5z;d%t~aaV8~=B2FU_3NM8g)BtsN~HIh3V6*Q+WlVcQNhbo@DTS0kx zh&-df