//------------------------------------------------------------------------------ // Author: Gero Mueller // Copyright: (c) 2006 Gero Mueller // License: MIT License //------------------------------------------------------------------------------ #ifndef BLUECORE_VECTOR_H #define BLUECORE_VECTOR_H // system includes #include #include // project includes #include "Scalar.h" namespace BlueCore { template class Vector3Template { public: T x, y, z; /** * Default Contructor */ inline Vector3Template() { x = static_cast(0); y = static_cast(0); z = static_cast(0); } /** * Constructor from three values */ template inline Vector3Template( S x, S y, S z ) { this->x = static_cast(x); this->y = static_cast(y); this->z = static_cast(z); } /** * copy contructor */ template inline Vector3Template( Vector3Template &a ) { x = static_cast(a.x); y = static_cast(a.y); z = static_cast(a.z); } /** * add operataor */ template inline Vector3Template operator + ( const Vector3Template &a ) const { return Vector3Template( x + static_cast(a.x), y + static_cast(a.y), z + static_cast(a.z) ); } /** * zero the vector */ inline void zero() { x = static_cast(0); y = static_cast(0); z = static_cast(0); } /** * zero the vector */ inline bool isZero() const { if( x != 0.0 ) return false; if( y != 0.0 ) return false; if( z != 0.0 ) return false; return true; } /** * add-assign operator */ template inline Vector3Template &operator += ( const Vector3Template &a ) { x += static_cast(a.x); y += static_cast(a.y); z += static_cast(a.z); return *this; } /** * sub operator */ template inline Vector3Template operator - ( const Vector3Template &a ) const { return Vector3Template( x - static_cast(a.x), y - static_cast(a.y), z - static_cast(a.z) ); } /** * sub-assign operator */ template inline Vector3Template &operator -= ( const Vector3Template &a ) { x -= static_cast(a.x); y -= static_cast(a.y); z -= static_cast(a.z); return *this; } /** * multiply by scalar operator */ template inline Vector3Template operator * ( const S a ) const { return Vector3Template( x * static_cast(a), y * static_cast(a), z * static_cast(a) ); } /** * multiply-assign by scalar operator */ template inline Vector3Template &operator *= ( const S a ) { x *= static_cast(a); y *= static_cast(a); z *= static_cast(a); return *this; } /** * divide by scalar operator */ template inline Vector3Template operator / ( const S a ) const { return Vector3Template( x / static_cast(a), y / static_cast(a), z / static_cast(a) ); } /** * divide-assign by scalar operator */ template inline Vector3Template &operator /= ( const S a ) { x /= static_cast(a); y /= static_cast(a); z /= static_cast(a); return *this; } /** * assign operator */ template inline Vector3Template operator = ( const Vector3Template &a ) { x = static_cast(a.x); y = static_cast(a.y); z = static_cast(a.z); return *this; } inline Vector3Template operator - (void) const { return Vector3Template( -x, -y, -z ); } /** * compare operator */ template inline bool operator == ( const Vector3Template &a ) { if( x != static_cast(a.x) ) return false; if( y != static_cast(a.y) ) return false; if( z != static_cast(a.z) ) return false; return true; } /** * anti compare operator */ template inline bool operator != ( const Vector3Template &a ) { if( x != static_cast(a.x) ) return true; if( y != static_cast(a.y) ) return true; if( z != static_cast(a.z) ) return true; return false; } /** * return the length of the vector */ inline T length() const { return static_cast( sqrt(x*x + y*y + z*z) ); } /** * length squared */ inline T length2() const { return x*x + y*y + z*z; } /** * calculate the cross product */ template inline Vector3Template cross( const Vector3Template &a ) const { return Vector3Template( y * static_cast(a.z) - z * static_cast(a.y), z * static_cast(a.x) - x * static_cast(a.z), x * static_cast(a.y) - y * static_cast(a.x) ); } /** * calculate dot product */ template inline T dot( const Vector3Template &a ) const { return ( x * static_cast(a.x) + y * static_cast(a.y) + z * static_cast(a.z) ); } /** * check if vectors are nearly equal */ template inline bool nearlyEquals( const Vector3Template &a, T epsilon = 0.00001 ) const { if( fabs(x-static_cast(a.x)) > epsilon ) return false; if( fabs(y-static_cast(a.y)) > epsilon ) return false; if( fabs(z-static_cast(a.z)) > epsilon ) return false; return true; } /** * normalize the vector to length 1 */ inline void normalize() { T a = length(); if( a == 0 ) return; x /= a; y /= a; z /= a; } /** * get normalized vector */ inline Vector3Template normalized() const { T a = length(); if( a == 0 ) return Vector3Template( 0.0, 0.0, 1.0 ); return Vector3Template( x / a, y / a, z / a ); } /** * check if vectors are parallel */ inline bool parallel( const Vector3Template &a ) const { return ( (static_cast(a.x) / x) == (static_cast(a.y) / y) == (static_cast(a.z) / z) ); } /** * check if vectors are parallel */ template inline bool nearlyParallel( const Vector3Template &a, T epsilon = 0.00001 ) const { T ax = static_cast(a.x) / x; T ay = static_cast(a.y) / y; T az = static_cast(a.z) / z; if( fabs(ax - ay) > epsilon ) return false; if( fabs(ax - az) > epsilon ) return false; if( fabs(ay - az) > epsilon ) return false; return true; } /** * check if vectors are orthogonal */ inline bool orthogonal( const Vector3Template &a ) const { return ( dot(a) == static_cast(0) ); } /** * check if vectors are orthogonal */ template inline bool nearlyOrthogonal( const Vector3Template &a, T epsilon = 0.00001 ) const { return ( dot(a) < epsilon ); } T& operator[] (unsigned int i) { if( i == 0 ) return x; else if( i == 1 ) return y; else if( i == 2 ) return z; else throw "index out of bound"; } friend std::ostream &operator << ( std::ostream& os, Vector3Template v ) { os << "( " << v.x << ", " << v.y << ", " << v.z << " )"; return os; } }; typedef Vector3Template Vector3Float; typedef Vector3Template Vector3Double; typedef Vector3Template Vector3; } #endif