Quaternion.cs
上传用户:huazai0421
上传日期:2008-05-30
资源大小:405k
文件大小:6k
源码类别:

SilverLight

开发平台:

C#

  1. // Silver.Globe, version 0.11 for Silverlight 1.1 Alpha
  2. // Copyright © Florian Krüsch (xaml-kru.com)
  3. // xaml-kru.com/silverglobe
  4. // This source is subject to the Microsoft Public License (Ms-PL).
  5. // See http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx.
  6. // All other rights reserved.
  7. using System;
  8. namespace SilverGlobe.Math3D
  9. {
  10.     /// <summary>
  11.     /// Represents a quaternion structure. 
  12.     /// </summary>
  13.     public struct Quaternion
  14.     {
  15.         #region Members
  16.         private Double _w, _x, _y, _z;
  17.         #endregion
  18.         #region Properties
  19.         public Double W 
  20.         {
  21.             get { return _w; }
  22.             set { _w = value; }
  23.         }
  24.         public Double X
  25.         {
  26.             get { return _x; }
  27.             set { _x = value; }
  28.         }
  29.         public Double Y
  30.         {
  31.             get { return _y; }
  32.             set { _y = value; }
  33.         }
  34.         public Double Z
  35.         {
  36.             get { return _z; }
  37.             set { _z = value; }
  38.         }
  39.         /// <summary>
  40.         /// Get the conjugate of the quaternion.
  41.         /// </summary>
  42.         public Quaternion Conjugate
  43.         {
  44.             get { return new Quaternion(_w, -_x, -_y, -_z); }
  45.         }
  46.         /// <summary>
  47.         /// Get the axis of the quaternion rotation.
  48.         /// </summary>
  49.         public Vector3D Axis
  50.         {
  51.             get
  52.             {
  53.                 Vector3D v = new Vector3D(_x, _y, _z).Normalized;
  54.                 if (v == Vector3D.Empty) v = Vector3D.YAxis;
  55.                 return v;
  56.             }
  57.         }
  58.         #endregion
  59.         #region Constructor
  60.         public Quaternion(Double w, Double x, Double y, Double z) : this()
  61.         {
  62.             _w = w;
  63.             _x = x;
  64.             _y = y;
  65.             _z = z;
  66.         }
  67.         #endregion
  68.         #region Methods
  69.         /// <summary>
  70.         /// Create a quaternion for an axis rotation.
  71.         /// </summary>
  72.         public static Quaternion ForRotation(Vector3D axis, Double angle)
  73.         {
  74.             Double a = 0.5 * angle * Math.PI / 180d;
  75.             Vector3D v = axis * Math.Sin(a);
  76.             return new Quaternion(Math.Cos(a), v.X, v.Y, v.Z);
  77.         }
  78.         /// <summary>
  79.         /// Calculate the inner product of two quaternions.
  80.         /// </summary>
  81.         public Double Dot(Quaternion b)
  82.         {
  83.             Quaternion a = this;
  84.             return a._w * b._w + a._x * b._x + a._y * b._y + a._z * b._z;
  85.         }
  86.         /// <summary>
  87.         /// Normalize the quaternion.
  88.         /// </summary>
  89.         public void Normalize()
  90.         {
  91.             Double length = Math.Sqrt(_w * _w + _z * _z + _y * _y + _x * _x);
  92.             _w /= length;
  93.             _x /= length;
  94.             _y /= length;
  95.             _z /= length;
  96.         }
  97.         /// <summary>
  98.         /// Convert the quaternion to a matrix.
  99.         /// </summary>
  100.         public Matrix3D ToMatrix()
  101.         {
  102.             Quaternion q = this;
  103.             Double w2 = q.W * q.W;
  104.             Double x2 = q.X * q.X;
  105.             Double y2 = q.Y * q.Y;
  106.             Double z2 = q.Z * q.Z;
  107.             Double xy_2 = 2 * q.X * q.Y;
  108.             Double wz_2 = 2 * q.W * q.Z;
  109.             Double wy_2 = 2 * q.W * q.Y;
  110.             Double wx_2 = 2 * q.W * q.X;
  111.             Double xz_2 = 2 * q.X * q.Z;
  112.             Double yz_2 = 2 * q.Y * q.Z;
  113.             return new Matrix3D
  114.             (
  115.                 w2 + x2 - y2 - z2, xy_2 + wz_2, xz_2 - wy_2, 0,
  116.                 xy_2 - wz_2, w2 - x2 + y2 - z2, yz_2 + wx_2, 0,
  117.                 xz_2 + wy_2, yz_2 - wx_2, w2 - x2 - y2 + z2, 0,
  118.                 0, 0, 0, w2 + x2 + y2 + z2
  119.             );
  120.         }
  121.         #endregion
  122.         #region Equality
  123.         public override Boolean Equals(object o)
  124.         {
  125.             if (!(o is Quaternion)) return false;
  126.             return Equals((Quaternion)o);
  127.         }
  128.         public Boolean Equals(Quaternion q)
  129.         {
  130.             return Equals(this, q);
  131.         }
  132.         public static Boolean Equals(Quaternion q1, Quaternion q2)
  133.         {
  134.             return q1._w == q2._w && q1._x == q2._x && q1._y == q2._y && q1._z == q2._z;
  135.         }
  136.         public override Int32 GetHashCode()
  137.         {
  138.             return _w.GetHashCode() ^ _x.GetHashCode() ^ _y.GetHashCode() ^ _z.GetHashCode();
  139.         }
  140.         #endregion
  141.         #region Operations
  142.         
  143.         public static Quaternion operator *(Quaternion q2, Quaternion q1)
  144.         {
  145.             return new Quaternion
  146.                    (
  147.                         q1.W * q2.W - q1.X * q2.X - q1.Y * q2.Y - q1.Z * q2.Z,
  148.                         q1.W * q2.X + q1.X * q2.W + q1.Y * q2.Z - q1.Z * q2.Y,
  149.                         q1.W * q2.Y + q1.Y * q2.W + q1.Z * q2.X - q1.X * q2.Z,
  150.                         q1.W * q2.Z + q1.Z * q2.W + q1.X * q2.Y - q1.Y * q2.X                    
  151.                    );
  152.         }
  153.         public static Quaternion operator *(Quaternion q, Double d)
  154.         {
  155.             return new Quaternion(q._w * d, q._x * d, q._y * d, q._z * d);
  156.         }
  157.         public static Quaternion operator +(Quaternion q1, Quaternion q2)
  158.         {
  159.             return new Quaternion
  160.                    (
  161.                         q1._w + q2._w,
  162.                         q1._x + q2._x,
  163.                         q1._y + q2._y,
  164.                         q1._z + q2._z                    
  165.                    );
  166.         }
  167.         public static Quaternion operator -(Quaternion q1, Quaternion q2)
  168.         {
  169.             return new Quaternion
  170.                    (
  171.                         q1._w - q2._w,
  172.                         q1._x - q2._x,
  173.                         q1._y - q2._y,
  174.                         q1._z - q2._z
  175.                    );
  176.         }
  177.         public static bool operator ==(Quaternion q1, Quaternion q2)
  178.         {
  179.             return q1.X == q2.X && q1.Y == q2.Y && q1.Z == q2.Z && q1.W == q2.W;
  180.         }
  181.         public static bool operator !=(Quaternion q1, Quaternion q2)
  182.         {
  183.             return (q1 != q2);
  184.         }
  185.         #endregion
  186.     }
  187. }