#ifndef __VECTOR_HEADER__ #define __VECTOR_HEADER__ // Stupid FLTK includes iostream.h, so I can't include the official // STL version of iostream. Damn it all to bloody hell! -- ehsu #include #include #pragma warning(push) #pragma warning(disable : 4244) //==========[ Forward References ]========================= template class Vec; template class Vec3; template class Vec4; template class Mat3; template class Mat4; //==========[ Exception Classes ]========================== class VectorSizeMismatch {}; //==========[ class Vec ]================================== template class Vec { // array of elements T* n; // vector size int numElements; public: //---[ Constructors/Destructor ]------------- Vec() { n = NULL; numElements = 0; } // creates a new vector with size elements // if zeroElements is true the vector is initialized to zero Vec( int size, bool zeroElements = false ); // copy constructor Vec( const Vec& v ); // destructor, simply deletes the array virtual ~Vec(); //---[ Size Methods ]------------------------ int size() const { return numElements; } void resize( int size, bool zeroElements = false ); //---[ Equal Operators ]--------------------- Vec& operator = ( const Vec& v ); Vec& operator += ( const Vec& v ); Vec& operator -= ( const Vec& v ); Vec& operator *= ( const T d ); Vec& operator /= ( const T d ); //---[ Access Operators ]-------------------- T& operator []( int i ) { return n[i]; } T operator []( int i ) const { return n[i]; } //---[ Arithmetic Operators ]---------------- Vec operator-( const Vec& a ); Vec operator+( const Vec& a ); //---[ Conversion Operators ]---------------- T* getPointer() const { return n; } //---[ Length Methods ]---------------------- double length2() const; double length() const; //---[ Normalization ]----------------------- void normalize(); //---[ Zero Test ]--------------------------- bool iszero(); void zeroElements(); //---[ Friend Methods ]---------------------- friend T operator *( const Vec& a, const Vec& b ); friend Vec operator -( const Vec& v ); friend Vec operator *( const Vec& a, const double d ); friend Vec operator *( const double d, const Vec& a ); friend Vec operator /( const Vec& a, const double d ); friend Vec operator ^( const Vec& a, const Vec& b ); friend bool operator ==( const Vec& a, const Vec& b ); friend bool operator !=( const Vec& a, const Vec& b ); friend ostream& operator <<( ostream& os, const Vec& v ); friend istream& operator >>( istream& is, Vec& v ); friend Vec minimum( const Vec& a, const Vec& b ); friend Vec maximum( const Vec& a, const Vec& b ); friend Vec prod( const Vec& a, const Vec& b ); }; typedef Vec Veci; typedef Vec Vecf; typedef Vec Vecd; //==========[ class Vec3 ]================================= template class Vec3 { //---[ Private Variable Declarations ]------- // x, y, z T n[3]; public: //---[ Constructors ]------------------------ Vec3() { n[0] = 0.0; n[1] = 0.0; n[2] = 0.0; } Vec3( const T x, const T y, const T z ) { n[0] = x; n[1] = y; n[2] = z; } Vec3( const Vec3& v ) { n[0] = v.n[0]; n[1] = v.n[1]; n[2] = v.n[2]; } //---[ Equal Operators ]--------------------- Vec3& operator=( const Vec3& v ) { n[0] = v.n[0]; n[1] = v.n[1]; n[2] = v.n[2]; return *this; } Vec3& operator +=( const Vec3& v ) { n[0] += v.n[0]; n[1] += v.n[1]; n[2] += v.n[2]; return *this; } Vec3& operator -= ( const Vec3& v ) { n[0] -= v.n[0]; n[1] -= v.n[1]; n[2] -= v.n[2]; return *this; } Vec3& operator *= ( const T d ) { n[0] *= d; n[1] *= d; n[2] *= d; return *this; } Vec3& operator /= ( const T d ) { n[0] /= d; n[1] /= d; n[2] /= d; return *this; } //---[ Access Operators ]-------------------- T& operator []( int i ) { return n[i]; } T operator []( int i ) const { return n[i]; } //---[ Arithmetic Operators ]---------------- Vec3 operator-( const Vec3& a ) { return Vec3(n[0]-a.n[0],n[1]-a.n[1],n[2]-a.n[2]); } Vec3 operator+( const Vec3& a ) { return Vec3(a.n[0]+n[0],a.n[1]+n[1],a.n[2]+n[2]); } //---[ Conversion Operators ]---------------- const T* getPointer() const { return n; } //---[ Length Methods ]---------------------- double length2() const { return n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; } double length() const { return sqrt( length2() ); } //---[ Normalization ]----------------------- void normalize() { double len = length(); n[0] /= len; n[1] /= len; n[2] /= len; } //---[ Zero Test ]--------------------------- bool iszero() { return ( (n[0]==0 && n[1]==0 && n[2]==0) ? true : false); }; void zeroElements() { memset(n,0,sizeof(T)*3); } //---[ Friend Methods ]---------------------- friend T operator *( const Vec3& a, const Vec4& b ); friend T operator *( const Vec4& b, const Vec3& a ); friend Vec3 operator -( const Vec3& v ); friend Vec3 operator *( const Vec3& a, const double d ); friend Vec3 operator *( const double d, const Vec3& a ); friend Vec3 operator *( const Vec3& v, Mat4& a ); friend T operator *( const Vec3& a, const Vec3& b ); friend Vec3 operator *( const Mat3& a, const Vec3& v ); friend Vec3 operator *( const Vec3& v, const Mat3& a ); friend Vec3 operator *( const Mat4& a, const Vec3& v ); friend Vec3 operator /( const Vec3& a, const double d ); friend Vec3 operator ^( const Vec3& a, const Vec3& b ); friend bool operator ==( const Vec3& a, const Vec3& b ); friend bool operator !=( const Vec3& a, const Vec3& b ); friend ostream& operator <<( ostream& os, const Vec3& v ); friend istream& operator >>( istream& is, Vec3& v ); friend Vec3 minimum( const Vec3& a, const Vec3& b ); friend Vec3 maximum( const Vec3& a, const Vec3& b ); friend Vec3 prod( const Vec3& a, const Vec3& b ); }; typedef Vec3 Vec3i; typedef Vec3 Vec3f; typedef Vec3 Vec3d; //==========[ class Vec4 ]================================= template class Vec4 { //---[ Private Variable Declarations ]------- // x, y, z, w T n[4]; public: //---[ Constructors ]------------------------ Vec4() { n[0] = 0.0; n[1] = 0.0; n[2] = 0.0; n[3] = 0.0; } Vec4( const T x, const T y, const T z, const T w ) { n[0] = x; n[1] = y; n[2] = z; n[3] = w; } Vec4( const Vec4& v ) { n[0] = v.n[0]; n[1] = v.n[1]; n[2] = v.n[2]; n[3] = v.n[3]; } //---[ Equal Operators ]--------------------- Vec4& operator =( const Vec4& v ) { n[0] = v.n[0]; n[1] = v.n[1]; n[2] = v.n[2]; n[3] = v.n[3]; return *this; } Vec4& operator +=( const Vec4& v ) { n[0] += v.n[0]; n[1] += v.n[1]; n[2] += v.n[2]; n[3] += v.n[3]; return *this; } Vec4& operator -= ( const Vec4& v ) { n[0] -= v.n[0]; n[1] -= v.n[1]; n[2] -= v.n[2]; n[3] -= v.n[3]; return *this; } Vec4& operator *= ( const T d ) { n[0] *= d; n[1] *= d; n[2] *= d; n[3] *= d; return *this; } Vec4& operator /= ( const T d ) { n[0] /= d; n[1] /= d; n[2] /= d; n[3] /= d; return *this; } //---[ Access Operators ]-------------------- T& operator []( int i ) { return n[i]; } T operator []( int i ) const { return n[i]; } //---[ Arithmetic Operators ]---------------- Vec4 operator-( const Vec4& a ) { return Vec4(n[0]-a.n[0],n[1]-a.n[1],n[2]-a.n[2],n[3]-a.n[3]); } Vec4 operator+( const Vec4& a ) { return Vec4(a.n[0]+n[0],a.n[1]+n[1],a.n[2]+n[2],a.n[3]-n[3]); } //---[ Length Methods ]---------------------- double length2() const { return n[0]*n[0] + n[1]*n[1] + n[2]*n[2] + n[3]*n[3]; } double length() const { return sqrt( length2() ); } //---[ Zero Test ]--------------------------- bool isZero() const { return n[0]==0&&n[1]==0&&n[2]==0&&n[3]==0; } void zeroElements() { memset(n,0,4*sizeof(T)); } //---[ Normalization ]----------------------- void normalize() { double len = length(); n[0] /= len; n[1] /= len; n[2] /= len; n[3] /= len; } //---[ Friend Methods ]---------------------- friend T operator *( const Vec3& a, const Vec4& b ); friend T operator *( const Vec4& b, const Vec3& a ); friend Vec4 operator -( const Vec4& v ); friend Vec4 operator *( const Vec4& a, const double d ); friend Vec4 operator *( const double d, const Vec4& a ); friend T operator *( const Vec4& a, const Vec4& b ); friend Vec4 operator *( const Mat4& a, const Vec4& v ); friend Vec4 operator *( const Vec4& v, const Mat4& a ); friend Vec4 operator /( const Vec4& a, const double d ); friend Vec4 operator ^( const Vec4& a, const Vec4& b ); friend bool operator ==( const Vec4& a, const Vec4& b ); friend bool operator !=( const Vec4& a, const Vec4& b ); friend ostream& operator <<( ostream& os, const Vec4& v ); friend istream& operator >>( istream& is, Vec4& v ); friend Vec4 minimum( const Vec4& a, const Vec4& b ); friend Vec4 maximum( const Vec4& a, const Vec4& b ); friend Vec4 prod( const Vec4& a, const Vec4& b ); }; typedef Vec4 Vec4i; typedef Vec4 Vec4f; typedef Vec4 Vec4d; //==========[ Vec Methods ]================================ template Vec::Vec( int size, bool zeroElements ) { numElements = size; n = new T[size]; if( !zeroElements ) return; for( int i=0;i Vec::Vec( const Vec& v ) { numElements = v.numElements; n = new T[numElements]; memcpy( n, v.n, numElements * sizeof(T) ); } template Vec::~Vec() { delete [] n; } template void Vec::resize( int size, bool zeroElements ) { if( numElements != size ) { numElements = size; if( n != NULL ) delete [] n; n = new T[size]; } if( zeroElements ) memset( n, 0, numElements * sizeof(T) ); } template void Vec::zeroElements() { memset( n, 0, numElements * sizeof(T) ); } template Vec& Vec::operator=( const Vec& v ) { #ifdef _DEBUG if( v.numElements != numElements ) throw VectorSizeMismatch(); #endif for( int i=0;i Vec& Vec::operator+=( const Vec& v ) { #ifdef _DEBUG if( v.numElements != numElements ) throw VectorSizeMismatch(); #endif for( int i=0;i Vec& Vec::operator-=( const Vec& v ) { #ifdef _DEBUG if( v.numElements != numElements ) throw VectorSizeMismatch(); #endif for( int i=0;i Vec& Vec::operator*=( const T d ) { for( int i=0;i Vec& Vec::operator/=( const T d ) { for( int i=0;i Vec Vec::operator-( const Vec& v ) { #ifdef _DEBUG if( v.numElements != numElements ) throw VectorSizeMismatch(); #endif Vec result( numElements, false ); for( int i=0;i Vec Vec::operator+( const Vec& v ) { #ifdef _DEBUG if( v.numElements != numElements ) throw VectorSizeMismatch(); #endif Vec result( numElements, false ); for( int i=0;i double Vec::length2() const { double result = 0.0; for( int i=0;i double Vec::length() const { return sqrt( length2() ); } template void Vec::normalize() { double len = length(); for( int i=0;i bool Vec::iszero() { for( int i=0;i T operator*( const Vec& a, const Vec& b ) { #ifdef _DEBUG if( a.numElements != b.numElements ) throw VectorSizeMismatch(); #endif double result = 0.0; for( int i=0;i Vec operator-( const Vec& v ) { Vec result( v.numElements, false ); for( int i=0;i Vec operator*( const Vec& a, const double d ) { Vec result( a.numElements, false ); for( int i=0;i Vec operator*( const double d, const Vec& a ) { Vec result( a.numElements, false ); for( int i=0;i Vec operator/( const Vec& a, const double d ) { Vec result( a.numElements, false ); for( int i=0;i Vec operator^( const Vec& a, const Vec& b ) { #ifdef _DEBUG if( a.numElements != b.numElements ) throw VectorSizeMismatch(); #endif return *this; } template bool operator==( const Vec& a, const Vec& b ) { #ifdef _DEBUG if( a.numElements != b.numElements ) throw VectorSizeMismatch(); #endif for( int i=0;i bool operator!=( const Vec& a, const Vec& b ) { #ifdef _DEBUG if( a.numElements != b.numElements ) throw VectorSizeMismatch(); #endif for( int i=0;i ostream& operator<<( ostream& os, const Vec& a ) { os << a.numElements; for( int i=0;i istream& operator>>( istream& is, const Vec& a ) { return is; } template Vec minimum( const Vec& a, const Vec& b ) { #ifdef _DEBUG if( a.numElements != b.numElements ) throw VectorSizeMismatch(); #endif Vec result( a.numElements, false ); for( int i=0;i Vec maximum( const Vec& a, const Vec& b ) { #ifdef _DEBUG if( a.numElements != b.numElements ) throw VectorSizeMismatch(); #endif Vec result( a.numElements, false ); for( int i=0;i Vec prod( const Vec& a, const Vec& b ) { #ifdef _DEBUG if( a.numElements != b.numElements ) throw VectorSizeMismatch(); #endif Vec result( a.numElements, false ); for( int i=0;i inline T operator *( const Vec3& a, const Vec4& b ) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3]; } template inline T operator *( const Vec4& b, const Vec3& a ) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3]; } template inline Vec3 operator -(const Vec3& v) { return Vec3( -v.n[0], -v.n[1], -v.n[2] ); } template inline Vec3 operator *(const Vec3& a, const double d ) { return Vec3( a.n[0] * d, a.n[1] * d, a.n[2] * d ); } template inline Vec3 operator *(const double d, const Vec3& a) { return a * d; } template inline Vec3 operator *(const Mat4& a, const Vec3& v){ return Vec3( a.n[0]*v.n[0]+a.n[1]*v.n[1]+a.n[2]*v.n[2]+a.n[3], a.n[4]*v.n[0]+a.n[5]*v.n[1]+a.n[6]*v.n[2]+a.n[7], a.n[8]*v.n[0]+a.n[9]*v.n[1]+a.n[10]*v.n[2]+a.n[11] ); } template inline Vec3 operator *(const Vec3& v, Mat4& a) { return a.transpose() * v; } template inline T operator *(const Vec3& a, const Vec3& b){ return a.n[0]*b.n[0] + a.n[1]*b.n[1] + a.n[2]*b.n[2]; } template inline Vec3 operator *( const Mat3& a, const Vec3& v ) { return Vec3( a.n[0]*v.n[0]+a.n[1]*v.n[1]+a.n[2]*v.n[2], a.n[3]*v.n[0]+a.n[4]*v.n[1]+a.n[5]*v.n[2], a.n[6]*v.n[0]+a.n[7]*v.n[1]+a.n[8]*v.n[2] ); } template inline Vec3 operator *( const Vec3& v, const Mat3& a ) { return a.transpose() * v; } template inline Vec3 operator /(const Vec3& a, const double d){ return Vec3( a.n[0] / d, a.n[1] / d, a.n[2] / d ); } template inline Vec3 operator ^(const Vec3& a, const Vec3& b) { return Vec3( a.n[1]*b.n[2] - a.n[2]*b.n[1], a.n[2]*b.n[0] - a.n[0]*b.n[2], a.n[0]*b.n[1] - a.n[1]*b.n[0] ); } template inline bool operator ==(const Vec3& a, const Vec3& b) { return a.n[0]==b.n[0] && a.n[1] == b.n[1] && a.n[2] == b.n[2]; } template inline bool operator !=(const Vec3& a, const Vec3& b) { return !( a == b ); } template inline ostream& operator <<( ostream& os, const Vec3& v ) { return os << "[" << v[0] << " " << v[1] << " " << v[2] << "]"; } template inline istream& operator >>( istream& is, Vec3& v ) { return is >> v.n[0] >> v.n[1] >> v.n[2]; } template inline void swap( Vec3& a, Vec3& b ) { Vec3 t( a ); a = b; b = t; } template inline Vec3 minimum( const Vec3& a, const Vec3& b ) { return Vec3( minimum(a.n[0],b.n[0]), minimum(a.n[1],b.n[1]), minimum(a.n[2],b.n[2]) ); } template inline Vec3 maximum(const Vec3& a, const Vec3& b) { return Vec3( maximum(a.n[0],b.n[0]), maximum(a.n[1],b.n[1]), maximum(a.n[2],b.n[2]) ); } template inline Vec3 prod(const Vec3& a, const Vec3& b ) { return Vec3( a.n[0]*b.n[0], a.n[1]*b.n[1], a.n[2]*b.n[2] ); } template inline Vec4 operator -( const Vec4& v ) { return Vec4( -v.n[0], -v.n[1], -v.n[2], -v.n[3] ); } template inline Vec4 operator *(const Vec4& a, const double d ) { return Vec4( a.n[0] * d, a.n[1] * d, a.n[2] * d, a.n[3] * d ); } template inline Vec4 operator *(const double d, const Vec4& a) { return a * d; } template inline T operator *(const Vec4& a, const Vec4& b) { return a.n[0]*b.n[0] + a.n[1]*b.n[1] + a.n[2]*b.n[2] + a.n[3]*b.n[3]; } template inline Vec4 operator *(const Mat4& a, const Vec4& v) { return Vec4( a.n[0]*v.n[0]+a.n[1]*v.n[1]+a.n[2]*v.n[2]+a.n[3]*v.n[3], a.n[4]*v.n[0]+a.n[5]*v.n[1]+a.n[6]*v.n[2]+a.n[7]*v.n[3], a.n[8]*v.n[0]+a.n[9]*v.n[1]+a.n[10]*v.n[2]+a.n[11]*v.n[3], a.n[12]*v.n[0]+a.n[13]*v.n[1]+a.n[14]*v.n[2]+a.n[15]*v.n[3]); } template inline Vec4 operator *( const Vec4& v, const Mat4& a ){ return a.transpose() * v; } template inline Vec4 operator /(const Vec4& a, const double d) { return Vec4( a.n[0] / d, a.n[1] / d, a.n[2] / d, a.n[3] / d ); } template inline bool operator ==(const Vec4& a, const Vec4& b) { return a.n[0] == b.n[0] && a.n[1] == b.n[1] && a.n[2] == b.n[2] && a.n[3] == b.n[3]; } template inline bool operator !=(const Vec4& a, const Vec4& b) { return !( a == b ); } template inline ostream& operator <<( ostream& os, const Vec4& v ) { return os << v.n[0] << " " << v.n[1] << " " << v.n[2] << " " << v.n[3]; } template inline istream& operator >>( istream& is, Vec4& v ) { return is >> v.n[0] >> v.n[1] >> v.n[2] >> v.n[3]; } template inline void swap( Vec4& a, Vec4& b ) { Vec4 t( a ); a = b; b = t; } template inline Vec4 minimum( const Vec4& a, const Vec4& b ) { return Vec4( minimum(a.n[0],b.n[0]), minimum(a.n[1],b.n[1]), minimum(a.n[2],b.n[2]), minimum(a.n[3],b.n[3]) ); } template inline Vec4 maximum(const Vec4& a, const Vec4& b) { return Vec4( maximum(a.n[0],b.n[0]), maximum(a.n[1],b.n[1]), maximum(a.n[2],b.n[2]), maximum(a.n[3],b.n[3]) ); } template inline Vec4 prod(const Vec4& a, const Vec4& b ) { return Vec4( a.n[0]*b.n[0], a.n[1]*b.n[1], a.n[2]*b.n[2], a.n[3]*b.n[3] ); } #pragma warning(pop) #endif