/* Hyperbolic Tessellations Copyright (C) 2007 Dmitry Brant http://dmitrybrant.com Based largely on code from http://www.plunk.org/~hatch/HyperbolicApplet/ */ #ifndef _myvector_h #define _myvector_h template class Vector { public: T* data; int length; Vector():length(0), data(NULL) { } ~Vector(){ if(data){ delete [] data; data = NULL; } } Vector(int _length):length(_length) { data = new T[_length]; } Vector(T* _data, int _length){ length = _length; data = new T[length]; for(int i=0; i& operator=(const Vector& a){ if(a.length != length){ if(data){ delete [] data; data = NULL; } length = a.length; data = new T[length]; } for(int i=0; i=0; i--) data[i] *= t; return *this; } inline Vector& operator/=(const T& t){ for(int i=length-1; i>=0; i--) data[i] *= t; return *this; } inline Vector& operator+=(const Vector& a){ for(int i=length-1; i>=0; i--) data[i] += a.data[i]; return *this; } inline Vector& operator-=(const Vector& a){ for(int i=length-1; i>=0; i--) data[i] -= a.data[i]; return *this; } /* String toString(){ String s; for(int i=length-1; i>=0; i--) s += String(data[i]) + " "; return s; } */ }; //template vector functions //dot product of two vectors (any length, as long as they're equal) inline template T dot(const Vector& v0, const Vector& v1){ T result=0; for(int i=v0.length-1; i>=0; i--) result += v0[i]*v1[i]; return result; } // perp dot // only makes sense for length 2 inline template Vector xv2(const Vector& v){ return complex(-v[1],v[0]); } // determinant of matrix having the two vectors as rows // or cross product in two dimensions // only makes sense for length 2 inline template T vxv2(const Vector& v, const Vector& w){ return v[0]*w[1] - v[1]*w[0]; } //cross product in three dimensions //only makes sense for length 3 inline template Vector vxv3(const Vector& v1, const Vector& v2){ Vector result(3); result[0] = v1[1]*v2[2] - v1[2]*v2[1]; result[1] = v1[2]*v2[0] - v1[0]*v2[2]; result[2] = v1[0]*v2[1] - v1[1]*v2[0]; return result; } // determinant of matrix having the three vectors as rows // only makes sense for length 3 inline template T vxvxv3(const Vector& v0, const Vector& v1, const Vector& v2){ return v0[0] * (v1[1]*v2[2] - v1[2]*v2[1]) + v0[1] * (v1[2]*v2[0] - v1[0]*v2[2]) + v0[2] * (v1[0]*v2[1] - v1[1]*v2[0]); } // ||b-a||^2 ||c-a||^2 - (b-a)dot(c-a) inline template T sqrdTwiceTriangleArea(const Vector& a, const Vector& b, const Vector& c){ T ab_dot_ab = 0.; T ab_dot_ac = 0.; T ac_dot_ac = 0.; for(int i=a.length-1; i>=0; i--){ T ai = a[i]; T ab = b[i] - ai; T ac = c[i] - ai; ab_dot_ab += ab*ab; ab_dot_ac += ab*ac; ac_dot_ac += ac*ac; } return ab_dot_ab*ac_dot_ac - (ab_dot_ac*ab_dot_ac); } // sqrdTwiceTriangleArea inline template T normsqrd(const Vector& v){ return dot(v,v); } inline template T norm(const Vector& v){ return sqrt(dot(v,v)); } inline template void normalize(Vector& result, const Vector& v){ T len = norm(v); result = v; result *= (len==0. ? 1. : 1./len); } inline template T distsqrd(const Vector& v0, const Vector& v1){ T result = 0.; for(int i=v0.length-1; i>=0; i--){ T diff = v1[i]-v0[i]; result += diff*diff; } return result; } inline template T dist(const Vector& v0, const Vector& v1){ return sqrt(distsqrd(v0, v1)); } inline template T angleBetweenUnitVectors(const Vector& u0, const Vector& u1){ // XXX can we cleverly avoid the square root? if (dot(u0, u1) > 0) return 2*asin(.5*dist(u0,u1)); else{ Vector minusU1 = u1; minusU1 *= -1.; return PI - 2*asin(.5*dist(u0,minusU1)); } } #define DoubleVector Vector #define IntVector Vector #endif