Quaternion Patch
Posted Thursday, 17 July, 2008 - 02:01 by Kamujin in
Here is a patch for the Quaternion class with a bug fix for ToAxisAngle and some overrides for equality comparison and get hash.
@@ -18,7 +18,7 @@
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
- public struct Quaternion
+ public struct Quaternion : IEquatable<Quaternion>
{
#region Fields
@@ -85,6 +85,10 @@
{
axis = q.XYZ / den;
}
+ else
+ {
+ axis = Vector3.UnitX;
+ }
}
#endregion
@@ -172,6 +176,28 @@
return left;
}
+ /// <summary>
+ /// Compares two Quaternions for equality.
+ /// </summary>
+ /// <param name="left">The first Quaternion to be used in the comparison.</param>
+ /// <param name="right">The second Quaternion to be used in the comparison.</param>
+ /// <returns>True if both Quaternions are equal. Otherwise it returns false.</returns>
+ public static bool operator ==(Quaternion left, Quaternion right)
+ {
+ return left.Equals(right);
+ }
+
+ /// <summary>
+ /// Compares two Quaternions for inequality.
+ /// </summary>
+ /// <param name="left">The first Quaternion to be used in the comparison.</param>
+ /// <param name="right">The second Quaternion to be used in the comparison.</param>
+ /// <returns>True if both Quaternions are not equal. Otherwise it returns false.</returns>
+ public static bool operator !=(Quaternion left, Quaternion right)
+ {
+ return !left.Equals(right);
+ }
+
[CLSCompliant(false)]
unsafe public static explicit operator float*(Quaternion q)
{
@@ -455,6 +481,37 @@
return String.Format("V: {0}, W: {1}", XYZ, W);
}
+ /// <summary>
+ /// Compares this Quaternion instance to another Quaternion for equality.
+ /// </summary>
+ /// <param name="other">The other Quaternion to be used in the comparison.</param>
+ /// <returns>True if both Quaternions are equal. Otherwise it returns false.</returns>
+ public bool Equals(Quaternion other)
+ {
+ return XYZ == other.XYZ
+ && W == other.W;
+ }
+
+ /// <summary>
+ /// Compares this object instance to another object for equality.
+ /// </summary>
+ /// <param name="other">The other object to be used in the comparison.</param>
+ /// <returns>True if both objects are Quaternions of equal value. Otherwise it returns false.</returns>
+ public override bool Equals (object o)
+ {
+ if (o is Quaternion == false) return false;
+ return this == (Quaternion)o;
+ }
+
+ /// <summary>
+ /// Provides the hash code for this object.
+ /// </summary>
+ /// <returns>A hash code formed from the bitwise XOR of this objects members.</returns>
+ public override int GetHashCode ()
+ {
+ return XYZ.GetHashCode() ^ W.GetHashCode();
+ }
+
#endregion
}
}
/// </summary>
[Serializable]
[StructLayout(LayoutKind.Sequential)]
- public struct Quaternion
+ public struct Quaternion : IEquatable<Quaternion>
{
#region Fields
@@ -85,6 +85,10 @@
{
axis = q.XYZ / den;
}
+ else
+ {
+ axis = Vector3.UnitX;
+ }
}
#endregion
@@ -172,6 +176,28 @@
return left;
}
+ /// <summary>
+ /// Compares two Quaternions for equality.
+ /// </summary>
+ /// <param name="left">The first Quaternion to be used in the comparison.</param>
+ /// <param name="right">The second Quaternion to be used in the comparison.</param>
+ /// <returns>True if both Quaternions are equal. Otherwise it returns false.</returns>
+ public static bool operator ==(Quaternion left, Quaternion right)
+ {
+ return left.Equals(right);
+ }
+
+ /// <summary>
+ /// Compares two Quaternions for inequality.
+ /// </summary>
+ /// <param name="left">The first Quaternion to be used in the comparison.</param>
+ /// <param name="right">The second Quaternion to be used in the comparison.</param>
+ /// <returns>True if both Quaternions are not equal. Otherwise it returns false.</returns>
+ public static bool operator !=(Quaternion left, Quaternion right)
+ {
+ return !left.Equals(right);
+ }
+
[CLSCompliant(false)]
unsafe public static explicit operator float*(Quaternion q)
{
@@ -455,6 +481,37 @@
return String.Format("V: {0}, W: {1}", XYZ, W);
}
+ /// <summary>
+ /// Compares this Quaternion instance to another Quaternion for equality.
+ /// </summary>
+ /// <param name="other">The other Quaternion to be used in the comparison.</param>
+ /// <returns>True if both Quaternions are equal. Otherwise it returns false.</returns>
+ public bool Equals(Quaternion other)
+ {
+ return XYZ == other.XYZ
+ && W == other.W;
+ }
+
+ /// <summary>
+ /// Compares this object instance to another object for equality.
+ /// </summary>
+ /// <param name="other">The other object to be used in the comparison.</param>
+ /// <returns>True if both objects are Quaternions of equal value. Otherwise it returns false.</returns>
+ public override bool Equals (object o)
+ {
+ if (o is Quaternion == false) return false;
+ return this == (Quaternion)o;
+ }
+
+ /// <summary>
+ /// Provides the hash code for this object.
+ /// </summary>
+ /// <returns>A hash code formed from the bitwise XOR of this objects members.</returns>
+ public override int GetHashCode ()
+ {
+ return XYZ.GetHashCode() ^ W.GetHashCode();
+ }
+
#endregion
}
}




Comments
Jul 19
12:52:53Re: Quaternion Patch
posted by KamujinFiddler
Any chance I can get a yes/no/this sucks on this patch? I'd like to at least know you've seen it.
Jul 20
16:33:10Re: Quaternion Patch
posted by the FiddlerSorry, I've seen this. It's a yes (though it could use some comments), but I was looking for some way to verify quats work correctly (due to the other thread with the normalization bug).
Jul 21
16:29:17Re: Quaternion Patch
posted by KamujinI'll add some comments and repost the patch.
Jul 21
02:11:42Re: Quaternion Patch
posted by KamujinHows this version?
Jul 22
07:13:34Re: Quaternion Patch
posted by the FiddlerGreat, thanks!