LeapMath.h
Go to the documentation of this file.
00001 /******************************************************************************\
00002 * Copyright (C) 2012-2013 Leap Motion, Inc. All rights reserved.               *
00003 * Leap Motion proprietary and confidential. Not for distribution.              *
00004 * Use subject to the terms of the Leap Motion SDK Agreement available at       *
00005 * https://developer.leapmotion.com/sdk_agreement, or another agreement         *
00006 * between Leap Motion and you, your company or other organization.             *
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; /* Note: Assumes x, y, z are aligned in memory. */
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 }; // namespace Leap
01049 
01050 #endif // __LeapMath_h__


leap_motion
Author(s): Florian Lier , Mirza Shah , Isaac IY Saito
autogenerated on Sat Jun 8 2019 18:47:25