Laser Sensing Display for UI interfaces in the real world

Dependencies:   mbed

Fork of skinGames_forktest by Alvaro Cassinelli

Revision:
40:3ba2b0ea9f33
Parent:
31:5f039cbddee8
Child:
44:2432c218f191
diff -r 7c54b6bca0e2 -r 3ba2b0ea9f33 myVectorClass.h
--- a/myVectorClass.h	Wed Oct 16 15:54:39 2013 +0000
+++ b/myVectorClass.h	Wed Oct 16 16:14:27 2013 +0000
@@ -1,10 +1,10 @@
-// class vector2D (for the time being, only 2d):
+// classes for 2d and 3d vectors 
+
+#ifndef vectors_H
+#define vectors_H
 
 #include "mbed.h"
 
-#ifndef vector2D_H
-#define vector2D_H
-
 #ifndef DEG_TO_RAD
 #define DEG_TO_RAD (PI/180.0)
 #endif
@@ -25,6 +25,7 @@
 #define PI 3.14159265889
 #endif
 
+// =================  2D VECTORS ===================== 
 template <class T>
 class vector2D {
 
@@ -47,7 +48,7 @@
         //
         void    operator=( const vector2D& vec );    // I cannot declare this if we want also operator chaining?
         //vector2D & operator=( const vector2D& vec ); // this is to enable operator chaining (vec1=vec2=vec3). 
-        vector2D  operator+( const vector2D& vec ) const;
+        vector2D  operator+( const vector2D& vec ) const; // note: "const" here means that the member function will not alter any member variable
         vector2D& operator+=( const vector2D& vec );      // why it has an output? for doing vec1=vec2+=vec3? YES!!! (operator chaining). 
         vector2D  operator-( const vector2D& vec ) const;
         vector2D& operator-=( const vector2D& vec );
@@ -117,9 +118,97 @@
     
 };
 
-/////////////////
+// 3D VECTORS: 
+template <class T>
+class vector3D {
+
+    public:
+        
+        // Overloaded constructor with parameters:
+        vector3D( T _x=0.0f, T _y=0.0f ,  T _z=0.0f );
+        // note: we use the default copy constructor
+        
+        // Explicit setting:
+        void set( T _x, T _y, T _z );
+        void set( const vector3D& vec );
+        
+        // Comparison:
+        bool operator==( const vector3D& vec );
+        bool operator!=( const vector3D& vec );
+        bool match( const vector3D& vec, float tollerance=0.0001 );
+    
+        // Overloaded operators:
+        //
+        void    operator=( const vector3D& vec );    // I cannot declare this if we want also operator chaining?
+        //vector3D & operator=( const vector2D& vec ); // this is to enable operator chaining (vec1=vec2=vec3). 
+        vector3D  operator+( const vector3D& vec ) const;
+        vector3D& operator+=( const vector3D& vec );      // why it has an output? for doing vec1=vec2+=vec3? YES!!! (operator chaining). 
+        vector3D  operator-( const vector3D& vec ) const;
+        vector3D& operator-=( const vector3D& vec );
+        vector3D  operator*( const vector3D& vec ) const;
+        vector3D& operator*=( const vector3D& vec );
+        
+        // division "dimension by dimension" (like the matlab "./"):
+        vector3D  operator/( const vector3D& vec ) const;
+        vector3D& operator/=( const vector3D& vec );
+        // note: division by a vector is properly defined for 2d vectors: norm is divided and argument is substracted (complex division). 
+    
+    //operator overloading for float:
+    void       operator=( const T f);  // I cannot declare this if we want also operator chaining?
+    //vector3D & operator=( const float& val ); // to allow operator chaining
+    vector3D  operator+( const T f ) const;
+    vector3D& operator+=( const T f );
+    vector3D  operator-( const T f ) const;
+    vector3D& operator-=( const T f );
+    vector3D  operator-() const;
+
+    
+    // multiplication by a scalar:
+    vector3D  operator*( const T f ) const;
+    vector3D& operator*=( const T f );
+    vector3D  operator/( const T f ) const;
+    vector3D& operator/=( const T f );    
+    
+    // Distance (between end points of two vector3Ds):
+    float distance( const vector3D& pnt) const;
+    float squareDistance( const vector3D& pnt ) const;
+    
+    // Length of vector3D (norm):
+    float length() const;
+    float squareLength() const; // faster, no sqrt
+    
+    // Scaling:
+    vector3D  getScaled( const float length ) const;
+    vector3D& scale( const float length );
+    
+    // Normalization:
+    vector3D  getNormalized() const;
+    vector3D& normalize();
+    
+    
+    //Angle (deg) between two vector2Ds (using atan2, so between -180 and 180)
+    float angleDeg( const vector3D& vec ) const;
+    float angleRad( const vector3D& vec ) const;
+    
+    //Dot Product:
+    float dot( const vector3D& vec ) const;
+    
+    //Cross product: 
+    vector3D  cross( const vector3D& vec ) const;
+    vector3D& cross( const vector3D& vec );
+    
+    // =================================================================
+    
+    // Actual variables:
+    T x, y, z; // or make a class "point"
+    
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // Implementation
-/////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// ============================================  2D vectors ============================================
 
 template <class T>
 inline vector2D<T>::vector2D( T _x, T _y ) {
@@ -422,10 +511,275 @@
     return x*vec.x + y*vec.y;
 }
 
+// ============================================  3D vectors ============================================
+
+template <class T>
+inline vector3D<T>::vector3D( T _x, T _y ,T _z ) {
+    x = _x; y = _y; z = _z;
+}
+
+template <class T>
+inline void vector3D<T>::set( T _x, T _y ,T _z ) {
+    x = _x; y = _y; z = _z;
+}
+
+template <class T>
+inline void vector3D<T>::set( const vector3D<T>& vec ) {
+    x=vec.x; y=vec.y; z = vec.z;
+}
+
+template <class T>
+inline bool vector3D<T>::operator==( const vector3D<T>& vec ) {
+    return (x == vec.x) && (y == vec.y)&& (z == vec.z);
+}
+
+template <class T>
+inline bool vector3D<T>::operator!=( const vector3D<T>& vec ) {
+    return (x != vec.x) || (y != vec.y)|| (z != vec.z);
+}
+
+template <class T>
+inline bool vector3D<T>::match( const vector3D<T>& vec, float tolerance ) {
+    return (abs(x - vec.x) < tolerance)&& (abs(y - vec.y) < tolerance)&& (abs(z - vec.z) < tolerance);
+}
+
+
+/*
+inline vector3D & operator=( const vector3D& vec ){ // returning a reference to the vector3D object for allowing operator chaining
+    x = vec.x;
+    y = vec.y;
+    return *this;
+}
+ */
+
+template <class T>
+inline void vector3D<T>::operator=( const vector3D<T>& vec ){
+    x = vec.x;  y = vec.y; z = vec.z;
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::operator+( const vector3D<T>& vec ) const {
+    return vector3D<T>( x+vec.x, y+vec.y, z+vec.z);
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::operator+=( const vector3D<T>& vec ) {
+    x += vec.x;
+    y += vec.y;
+    z += vec.z;
+    return *this;
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::operator-( const vector3D<T>& vec ) const {  
+    return vector3D<T>(x-vec.x, y-vec.y, z-vec.z);
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::operator-=( const vector3D<T>& vec ) {
+    x -= vec.x;
+    y -= vec.y;
+    z -= vec.z;
+    return *this;
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::operator*( const vector3D<T>& vec ) const {
+    return vector3D<T>(x*vec.x, y*vec.y, z*vec.z);
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::operator*=( const vector3D<T>& vec ) {
+    x*=vec.x;
+    y*=vec.y;
+    z*=vec.z;
+    return *this;
+}
+
+//operator overloading for float:
+/*
+inline vector3D<T> & operator=( const float& val ){
+    x = val;
+    y = val;
+    return *this;
+}
+ */
+
+template <class T>
+inline void vector3D<T>::operator=( const T f){
+    x = f;  y = f;  z = f;
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::operator+( const T f ) const {
+    return vector3D<T>( x+f, y+f, z+f);
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::operator+=( const T f ) {
+    x += f; y += f; z+=f;
+    return *this;
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::operator-( const T f ) const {
+    return vector3D<T>( x-f, y-f, z-f);
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::operator-=( const T f ) {
+    x -= f; y -= f; z-=f;
+    return *this;
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::operator-() const {
+    return vector3D<T>(-x, -y, -z);
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::operator*( const T f ) const {
+    return vector3D<T>(x*f, y*f, z*f);
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::operator*=( const T f ) {
+    x*=f; y*=f; z*=f;
+    return *this;
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::operator/( const T f ) const {
+    //cout << "here" << endl;
+    if(f == 0) return vector3D<T>(x, y);
+    return vector3D<T>(x/f, y/f, z/f);
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::operator/=( const T f ) {
+    if(f == 0) return *this;
+    x/=f; y/=f; z/=f;
+    return *this;
+}
+
+template <class T>
+inline vector3D<T> vector3D<T>::getScaled( const float length ) const {
+    float l = (float)sqrt(x*x + y*y + z*z);
+    if( l > 0 )
+        return vector3D<T>( (x/l)*length, (y/l)*length , (z/l)*length);
+    else
+        return vector3D<T>();
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::scale( const float length ) {
+    float l = (float)sqrt(x*x + y*y + z*z);
+    if (l > 0) {
+        x = (x/l)*length;
+        y = (y/l)*length;
+        z = (z/l)*length;
+    }
+    return *this;
+}
+
+
+template <class T>
+inline float vector3D<T>::distance( const vector3D<T>& pnt) const {
+    float vx = x-pnt.x;
+    float vy = y-pnt.y;
+    float vz = z-pnt.z;
+    return (float)sqrt(vx*vx + vy*vy + vz*vz);
+}
+
+template <class T>
+inline float vector3D<T>::squareDistance( const vector3D<T>& pnt ) const {
+    float vx = x-pnt.x;
+    float vy = y-pnt.y;
+    float vz = z-pnt.z;
+    return vx*vx + vy*vy+ vz*vz;
+}
+
+// Normalization:
+template <class T>
+inline vector3D<T> vector3D<T>::getNormalized() const {
+    float length = (float)sqrt(x*x + y*y + z*z);
+    if( length > 0 ) {
+        return vector3D<T>( x/length, y/length , z/length);
+    } else {
+        return vector3D<T>();
+    }
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::normalize() {
+    float length = (float)sqrt(x*x + y*y + z*z);
+    if( length > 0 ) {
+        x /= length;
+        y /= length;
+        z /= length;
+    }
+    return *this;
+}
+
+// Length (norm of vector3D<T>):
+template <class T>
+inline float vector3D<T>::length() const {
+    return (float)sqrt( x*x + y*y + z*z);
+}
+
+template <class T>
+inline float vector3D<T>::squareLength() const {
+    return (float)(x*x + y*y+ z*z);
+}
+
+// Angle between two vector3Ds:
+template <class T>
+inline float vector3D<T>::angleDeg( const vector3D<T>& vec ) const {
+//atan2(norm(cross(a,b)), dot(a,b))
+    return (float)(atan2( (this->cross(vec)).length(),this->dot(vec))*RAD_TO_DEG); 
+}
+
+template <class T>
+inline float vector3D<T>::angleRad( const vector3D<T>& vec ) const {
+    return atan2((this->cross(vec)).length(),this->dot(vec));
+}
+
+//Dot Product:
+template <class T>
+inline float vector3D<T>::dot( const vector3D<T>& vec ) const {
+    return x*vec.x + y*vec.y +  z*vec.z;
+}
+
+// Cross product: 
+template <class T>
+inline vector3D<T> vector3D<T>::cross( const vector3D<T>& vec ) const {
+    return vector3D<T>( y*vec.z - vec.y*z, -x*vec.z + vec.x * z, x.vec.y - vec.x* y);
+}
+
+template <class T>
+inline vector3D<T>& vector3D<T>::cross( const vector3D<T>& vec ) {
+    x = y*vec.z - vec.y*z;
+    y = -x*vec.z + vec.x * z;
+    z = x.vec.y - vec.x* y;
+    return *this;
+}
+
+// ======================================================================================
 
 //handy typedefs:
 typedef vector2D<short> vector2Dd;
 typedef vector2D<float> vector2Df;
+typedef vector3D<short> vector3Dd;
+typedef vector3D<float> vector3Df;
+
 
 
+// ================= other auxiliary structures ============
+typedef struct Box3d {
+    float minX, maxX; 
+    float minY, maxY; 
+    float minZ, maxZ; 
+};
+
 #endif
+