]> Dogcows Code - chaz/yoink/blobdiff - src/quaternion.hh
new classes; yajl library
[chaz/yoink] / src / quaternion.hh
diff --git a/src/quaternion.hh b/src/quaternion.hh
new file mode 100644 (file)
index 0000000..daf3114
--- /dev/null
@@ -0,0 +1,188 @@
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+ Redistribution   and   use  in  source  and  binary  forms,  with  or  without
+ modification, are permitted provided that the following conditions are met:
+   * Redistributions  of  source  code  must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+   * Redistributions  in binary form must reproduce the above copyright notice,
+     this  list of conditions and the following disclaimer in the documentation
+     and/or other materials provided with the distribution.
+ THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _QUATERNION_HH_
+#define _QUATERNION_HH_
+
+#include <cassert>
+
+#include "math.hh"
+#include "matrix.hh"
+#include "vector.hh"
+
+
+//
+// Quaternion -> 3x3 Matrix
+//
+// | w^2 + x^2 - y^2 - z^2         2xy - 2wz               2xz + 2yw       |
+// |       2xy + 2wz         w^2 - x^2 + y^2 - z^2         2yz - 2wx       |
+// |       2xz - 2wy               2yz - 2wx         w^2 - x^2 - y^2 + z^2 |
+//
+
+namespace dc {
+
+
+class quaternion
+{
+public:
+       // Constructors.
+       quaternion() {}
+       quaternion(scalar X, scalar Y, scalar Z, scalar W) {
+               vec.x = X; vec.y = Y; vec.z = Z; w = W;
+       }
+       quaternion(vector3 v, scalar W = 1.0) {
+               vec = v; w = W;
+       }
+       quaternion(scalar q[4]) {
+               vec.x = q[0]; vec.y = q[1]; vec.z = q[2]; w = q[3];
+       }
+
+       // Accessible by index.
+       const scalar& operator [] (int i) const {
+               assert(i >= 0 && i <= 3 && "Index into quaternion out of bounds.");
+               return *((&vec.x) + i);
+       }
+       scalar& operator [] (int i) {
+               assert(i >= 0 && i <= 3 && "Index into quaternion out of bounds.");
+               //return vec[i];
+               return *((&vec.x) + i);
+       }
+
+       // Basic maths.
+       quaternion operator + (const quaternion& q) const {
+               return quaternion(vec + q.vec, w + q.w);
+       }
+       quaternion operator - (const quaternion& q) const {
+               return quaternion(vec - q.vec, w - q.w);
+       }
+       quaternion operator * (const quaternion& q) const {
+               return quaternion(q.w * vec + w * q.vec + q.vec.cross(vec),
+                                                 w * q.w - q.vec.dot(vec));
+       }
+       quaternion operator * (scalar s) const {
+               return quaternion(vec * s, w * s);
+       }
+       quaternion operator / (scalar s) const {
+               return quaternion(vec / s, w / s);
+       }
+
+       quaternion& operator += (const quaternion& q) {
+               vec += q.vec; w += q.w;
+               return *this;
+       }
+       quaternion& operator -= (const quaternion& q) {
+               vec -= q.vec; w -= q.w;
+               return *this;
+       }
+       quaternion& operator *= (const quaternion& q) {
+               scalar W = w;
+               w = W * q.w - q.vec.dot(vec);
+               vec = q.w * vec + W * q.vec + q.vec.cross(vec);
+               return *this;
+       }
+       quaternion& operator *= (scalar s) {
+               vec *= s; w *= s;
+               return *this;
+       }
+       quaternion& operator /= (scalar s) {
+               vec /= s; w /= s;
+               return *this;
+       }
+
+       // Unary operators.
+       quaternion operator - () const {
+               return quaternion(-vec, -w);
+       }
+
+       // Quaternion operations.
+       quaternion conjugate() const {
+               return quaternion(-vec, w);
+       }
+       void normalize(const vector3& v)
+       {
+               scalar len = length();
+               if (len != 0.0) { *this /= len; }
+       }
+       
+       scalar length2() const {
+               return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z + w * w;
+       }
+       scalar length() const {
+               return std::sqrt(length2());
+       }
+
+       // Converting to other types.
+       matrix3 matrix() const {
+               scalar x2 = vec.x * vec.x;
+               scalar y2 = vec.y * vec.y;
+               scalar z2 = vec.z * vec.z;
+               scalar w2 = w * w;
+               scalar xy = vec.x * vec.y;
+               scalar xz = vec.x * vec.z;
+               scalar yzwx = 2 * (vec.y * vec.z - w * vec.x);
+               scalar wy = w * vec.y;
+               scalar wz = w * vec.z;
+               return matrix3(x2 - y2 - z2 + w2, 2 * (xy - wz), 2 * (xz + wy),
+                                          2 * (xy + wz), w2 - x2 + y2 - z2, yzwx,
+                                          2 * (xz - wy), yzwx, w2 - x2 - y2 + z2);
+       }
+       vector3 axis(scalar& angle) { // Axis of rotation, w/ angle of rotation.
+               vector3 axisVec = axis();
+               angle = 2 * std::acos(w);
+               return axisVec;
+       }
+       vector3 axis() {
+               scalar sa = std::sqrt(1 - w * w);
+               return vec / sa;
+       }
+
+       // Checking equality.
+       bool operator == (const quaternion& q) const {
+               return vec == q.vec && equals(w,q.w);
+       }
+       bool operator != (const quaternion& q) const {
+               return !(*this == q);
+       }
+
+       // Data.
+       vector3 vec;
+       scalar w;
+};
+
+inline quaternion operator * (scalar s, const quaternion& q) {
+       return q * s;
+}
+inline quaternion operator / (scalar s, const quaternion& q) {
+       return quaternion(s / q.vec, s / q.w);
+}
+
+} // namespace dc
+
+
+#endif // _QUATERNION_HH_
+
This page took 0.022792 seconds and 4 git commands to generate.