00001
00002
00003
00004
00005
00006
00007
00008
00009 #if !defined(__LeapMath_h__)
00010 #define __LeapMath_h__
00011
00012 #include <cmath>
00013 #include <iostream>
00014 #include <sstream>
00015 #include <float.h>
00016 #include <algorithm>
00017
00018 namespace Leap {
00019
00024 static const float PI = 3.1415926536f;
00030 static const float DEG_TO_RAD = 0.0174532925f;
00036 static const float RAD_TO_DEG = 57.295779513f;
00037
00043 static const float EPSILON = 1.192092896e-07f;
00044
00060 struct Vector {
00065 Vector() :
00066 x(0), y(0), z(0) {}
00067
00074 Vector(float _x, float _y, float _z) :
00075 x(_x), y(_y), z(_z) {}
00076
00083 Vector(const Vector& vector) :
00084 x(vector.x), y(vector.y), z(vector.z) {}
00085
00092 static const Vector& zero() {
00093 static Vector s_zero(0, 0, 0);
00094 return s_zero;
00095 }
00096
00103 static const Vector& xAxis() {
00104 static Vector s_xAxis(1, 0, 0);
00105 return s_xAxis;
00106 }
00113 static const Vector& yAxis() {
00114 static Vector s_yAxis(0, 1, 0);
00115 return s_yAxis;
00116 }
00123 static const Vector& zAxis() {
00124 static Vector s_zAxis(0, 0, 1);
00125 return s_zAxis;
00126 }
00127
00134 static const Vector& left() {
00135 static Vector s_left(-1, 0, 0);
00136 return s_left;
00137 }
00144 static const Vector& right() {
00145 return xAxis();
00146 }
00153 static const Vector& down() {
00154 static Vector s_down(0, -1, 0);
00155 return s_down;
00156 }
00163 static const Vector& up() {
00164 return yAxis();
00165 }
00172 static const Vector& forward() {
00173 static Vector s_forward(0, 0, -1);
00174 return s_forward;
00175 }
00182 static const Vector& backward() {
00183 return zAxis();
00184 }
00185
00197 float magnitude() const {
00198 return std::sqrt(x*x + y*y + z*z);
00199 }
00200
00209 float magnitudeSquared() const {
00210 return x*x + y*y + z*z;
00211 }
00212
00223 float distanceTo(const Vector& other) const {
00224 return std::sqrt((x - other.x)*(x - other.x) +
00225 (y - other.y)*(y - other.y) +
00226 (z - other.z)*(z - other.z));
00227 }
00228
00247 float angleTo(const Vector& other) const {
00248 float denom = this->magnitudeSquared() * other.magnitudeSquared();
00249 if (denom <= EPSILON) {
00250 return 0.0f;
00251 }
00252 float val = this->dot(other) / std::sqrt(denom);
00253 if (val >= 1.0f) {
00254 return 0.0f;
00255 } else if (val <= -1.0f) {
00256 return PI;
00257 }
00258 return std::acos(val);
00259 }
00260
00277 float pitch() const {
00278 return std::atan2(y, -z);
00279 }
00280
00297 float yaw() const {
00298 return std::atan2(x, -z);
00299 }
00300
00322 float roll() const {
00323 return std::atan2(x, -y);
00324 }
00325
00340 float dot(const Vector& other) const {
00341 return (x * other.x) + (y * other.y) + (z * other.z);
00342 }
00343
00360 Vector cross(const Vector& other) const {
00361 return Vector((y * other.z) - (z * other.y),
00362 (z * other.x) - (x * other.z),
00363 (x * other.y) - (y * other.x));
00364 }
00365
00378 Vector normalized() const {
00379 float denom = this->magnitudeSquared();
00380 if (denom <= EPSILON) {
00381 return Vector::zero();
00382 }
00383 denom = 1.0f / std::sqrt(denom);
00384 return Vector(x * denom, y * denom, z * denom);
00385 }
00386
00395 Vector operator-() const {
00396 return Vector(-x, -y, -z);
00397 }
00398
00405 Vector operator+(const Vector& other) const {
00406 return Vector(x + other.x, y + other.y, z + other.z);
00407 }
00408
00415 Vector operator-(const Vector& other) const {
00416 return Vector(x - other.x, y - other.y, z - other.z);
00417 }
00418
00425 Vector operator*(float scalar) const {
00426 return Vector(x * scalar, y * scalar, z * scalar);
00427 }
00428
00435 Vector operator/(float scalar) const {
00436 return Vector(x / scalar, y / scalar, z / scalar);
00437 }
00438
00439 #if !defined(SWIG)
00440
00446 friend Vector operator*(float scalar, const Vector& vector) {
00447 return Vector(vector.x * scalar, vector.y * scalar, vector.z * scalar);
00448 }
00449 #endif
00450
00455 Vector& operator+=(const Vector& other) {
00456 x += other.x;
00457 y += other.y;
00458 z += other.z;
00459 return *this;
00460 }
00461
00466 Vector& operator-=(const Vector& other) {
00467 x -= other.x;
00468 y -= other.y;
00469 z -= other.z;
00470 return *this;
00471 }
00472
00477 Vector& operator*=(float scalar) {
00478 x *= scalar;
00479 y *= scalar;
00480 z *= scalar;
00481 return *this;
00482 }
00483
00488 Vector& operator/=(float scalar) {
00489 x /= scalar;
00490 y /= scalar;
00491 z /= scalar;
00492 return *this;
00493 }
00494
00499 std::string toString() const {
00500 std::stringstream result;
00501 result << "(" << x << ", " << y << ", " << z << ")";
00502 return result.str();
00503 }
00508 friend std::ostream& operator<<(std::ostream& out, const Vector& vector) {
00509 return out << vector.toString();
00510 }
00511
00518 bool operator==(const Vector& other) const {
00519 return x == other.x && y == other.y && z == other.z;
00520 }
00527 bool operator!=(const Vector& other) const {
00528 return x != other.x || y != other.y || z != other.z;
00529 }
00530
00538 bool isValid() const {
00539 return (x <= FLT_MAX && x >= -FLT_MAX) &&
00540 (y <= FLT_MAX && y >= -FLT_MAX) &&
00541 (z <= FLT_MAX && z >= -FLT_MAX);
00542 }
00543
00553 float operator[](unsigned int index) const {
00554 return index < 3 ? (&x)[index] : 0.0f;
00555 }
00556
00563 const float* toFloatPointer() const {
00564 return &x;
00565 }
00566
00574 template<typename Vector3Type>
00575 const Vector3Type toVector3() const {
00576 return Vector3Type(x, y, z);
00577 }
00578
00588 template<typename Vector4Type>
00589 const Vector4Type toVector4(float w=0.0f) const {
00590 return Vector4Type(x, y, z, w);
00591 }
00592
00597 float x;
00602 float y;
00607 float z;
00608 };
00609
00610
00617 struct FloatArray {
00622 float& operator[] (unsigned int index) {
00623 return m_array[index];
00624 }
00625
00630 operator float* () {
00631 return m_array;
00632 }
00633
00638 operator const float* () const {
00639 return m_array;
00640 }
00641
00646 float m_array[16];
00647 };
00648
00660 struct Matrix
00661 {
00669 Matrix() :
00670 xBasis(1, 0, 0),
00671 yBasis(0, 1, 0),
00672 zBasis(0, 0, 1),
00673 origin(0, 0, 0) {
00674 }
00675
00683 Matrix(const Matrix& other) :
00684 xBasis(other.xBasis),
00685 yBasis(other.yBasis),
00686 zBasis(other.zBasis),
00687 origin(other.origin) {
00688 }
00689
00700 Matrix(const Vector& _xBasis, const Vector& _yBasis, const Vector& _zBasis) :
00701 xBasis(_xBasis),
00702 yBasis(_yBasis),
00703 zBasis(_zBasis),
00704 origin(0, 0, 0) {
00705 }
00706
00718 Matrix(const Vector& _xBasis, const Vector& _yBasis, const Vector& _zBasis, const Vector& _origin) :
00719 xBasis(_xBasis),
00720 yBasis(_yBasis),
00721 zBasis(_zBasis),
00722 origin(_origin) {
00723 }
00724
00734 Matrix(const Vector& axis, float angleRadians) :
00735 origin(0, 0, 0) {
00736 setRotation(axis, angleRadians);
00737 }
00738
00750 Matrix(const Vector& axis, float angleRadians, const Vector& translation)
00751 : origin(translation) {
00752 setRotation(axis, angleRadians);
00753 }
00754
00763 static const Matrix& identity() {
00764 static Matrix s_identity;
00765 return s_identity;
00766 }
00767
00780 void setRotation(const Vector& axis, float angleRadians) {
00781 const Vector n = axis.normalized();
00782 const float s = std::sin(angleRadians);
00783 const float c = std::cos(angleRadians);
00784 const float C = (1-c);
00785
00786 xBasis = Vector(n[0]*n[0]*C + c, n[0]*n[1]*C - n[2]*s, n[0]*n[2]*C + n[1]*s);
00787 yBasis = Vector(n[1]*n[0]*C + n[2]*s, n[1]*n[1]*C + c, n[1]*n[2]*C - n[0]*s);
00788 zBasis = Vector(n[2]*n[0]*C - n[1]*s, n[2]*n[1]*C + n[0]*s, n[2]*n[2]*C + c );
00789 }
00790
00803 Vector transformPoint(const Vector& in) const {
00804 return xBasis*in.x + yBasis*in.y + zBasis*in.z + origin;
00805 }
00806
00817 Vector transformDirection(const Vector& in) const {
00818 return xBasis*in.x + yBasis*in.y + zBasis*in.z;
00819 }
00820
00833 Matrix rigidInverse() const {
00834 Matrix rotInverse = Matrix(Vector(xBasis[0], yBasis[0], zBasis[0]),
00835 Vector(xBasis[1], yBasis[1], zBasis[1]),
00836 Vector(xBasis[2], yBasis[2], zBasis[2]));
00837 rotInverse.origin = rotInverse.transformDirection( -origin );
00838 return rotInverse;
00839 }
00840
00853 Matrix operator*(const Matrix& other) const {
00854 return Matrix(transformDirection(other.xBasis),
00855 transformDirection(other.yBasis),
00856 transformDirection(other.zBasis),
00857 transformPoint(other.origin));
00858 }
00859
00867 Matrix& operator*=(const Matrix& other) {
00868 return (*this) = (*this) * other;
00869 }
00870
00878 bool operator==(const Matrix& other) const {
00879 return xBasis == other.xBasis &&
00880 yBasis == other.yBasis &&
00881 zBasis == other.zBasis &&
00882 origin == other.origin;
00883 }
00891 bool operator!=(const Matrix& other) const {
00892 return xBasis != other.xBasis ||
00893 yBasis != other.yBasis ||
00894 zBasis != other.zBasis ||
00895 origin != other.origin;
00896 }
00897
00907 template<typename Matrix3x3Type>
00908 const Matrix3x3Type toMatrix3x3() const {
00909 return Matrix3x3Type(xBasis.x, xBasis.y, xBasis.z,
00910 yBasis.x, yBasis.y, yBasis.z,
00911 zBasis.x, zBasis.y, zBasis.z);
00912 }
00913
00921 template<typename Matrix4x4Type>
00922 const Matrix4x4Type toMatrix4x4() const {
00923 return Matrix4x4Type(xBasis.x, xBasis.y, xBasis.z, 0.0f,
00924 yBasis.x, yBasis.y, yBasis.z, 0.0f,
00925 zBasis.x, zBasis.y, zBasis.z, 0.0f,
00926 origin.x, origin.y, origin.z, 1.0f);
00927 }
00928
00938 template<typename T>
00939 T* toArray3x3(T* output) const {
00940 output[0] = xBasis.x; output[1] = xBasis.y; output[2] = xBasis.z;
00941 output[3] = yBasis.x; output[4] = yBasis.y; output[5] = yBasis.z;
00942 output[6] = zBasis.x; output[7] = zBasis.y; output[8] = zBasis.z;
00943 return output;
00944 }
00945
00956 FloatArray toArray3x3() const {
00957 FloatArray output;
00958 toArray3x3((float*)output);
00959 return output;
00960 }
00961
00969 template<typename T>
00970 T* toArray4x4(T* output) const {
00971 output[0] = xBasis.x; output[1] = xBasis.y; output[2] = xBasis.z; output[3] = 0.0f;
00972 output[4] = yBasis.x; output[5] = yBasis.y; output[6] = yBasis.z; output[7] = 0.0f;
00973 output[8] = zBasis.x; output[9] = zBasis.y; output[10] = zBasis.z; output[11] = 0.0f;
00974 output[12] = origin.x; output[13] = origin.y; output[14] = origin.z; output[15] = 1.0f;
00975 return output;
00976 }
00977
00986 FloatArray toArray4x4() const {
00987 FloatArray output;
00988 toArray4x4((float*)output);
00989 return output;
00990 }
00991
00996 std::string toString() const {
00997 std::stringstream result;
00998 result << "xBasis:" << xBasis.toString() << " yBasis:" << yBasis.toString()
00999 << " zBasis:" << zBasis.toString() << " origin:" << origin.toString();
01000 return result.str();
01001 }
01002
01010 friend std::ostream& operator<<(std::ostream& out, const Matrix& matrix) {
01011 return out << matrix.toString();
01012 }
01013
01021 Vector xBasis;
01029 Vector yBasis;
01037 Vector zBasis;
01045 Vector origin;
01046 };
01047
01048 };
01049
01050 #endif // __LeapMath_h__