Implemented IEquatable interface.

Fixed ToAxisAngle implementation at 0-degree angles.
Added ToAxisAngle overload that returns a Vector4 struct.
This commit is contained in:
the_fiddler 2009-02-13 19:53:46 +00:00
parent 92d79bb47b
commit 527fb19364
2 changed files with 79 additions and 21 deletions

View file

@ -32,7 +32,7 @@ namespace OpenTK.Math
/// </summary> /// </summary>
[Serializable] [Serializable]
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct Quaternion public struct Quaternion : IEquatable<Quaternion>
{ {
#region Fields #region Fields
@ -111,7 +111,7 @@ namespace OpenTK.Math
#region Instance #region Instance
#region pubilc void ToAxisAngle(out Vector3 axis, out float angle) #region ToAxisAngle
/// <summary> /// <summary>
/// Convert the current quaternion to axis angle representation /// Convert the current quaternion to axis angle representation
@ -120,19 +120,39 @@ namespace OpenTK.Math
/// <param name="angle">The resultant angle</param> /// <param name="angle">The resultant angle</param>
public void ToAxisAngle(out Vector3 axis, out float angle) public void ToAxisAngle(out Vector3 axis, out float angle)
{ {
Quaternion q = this; Vector4 result = ToAxisAngle();
if (q.W > 1.0f) axis = result.Xyz;
q.Normalize(); angle = result.W;
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;
}
} }
/// <summary>
/// Convert this instance to an axis-angle representation.
/// </summary>
/// <returns>A Vector4 that is the axis-angle representation of this quaternion.</returns>
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 #endregion
#region public float Length #region public float Length
@ -483,18 +503,14 @@ namespace OpenTK.Math
return left; return left;
} }
[CLSCompliant(false)] public static bool operator ==(Quaternion left, Quaternion right)
unsafe public static explicit operator float*(Quaternion q)
{ {
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 !left.Equals(right);
{
return (IntPtr)(&q.XYZ.X);
}
} }
#endregion #endregion
@ -514,8 +530,50 @@ namespace OpenTK.Math
#endregion #endregion
#region public override bool Equals (object o)
/// <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;
}
#endregion #endregion
#region public override int GetHashCode ()
/// <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
#endregion
#endregion
#region IEquatable<Quaternion> Members
/// <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 instances are equal; false otherwise.</returns>
public bool Equals(Quaternion other)
{
return XYZ == other.XYZ && W == other.W;
}
#endregion #endregion
} }
} }

Binary file not shown.