# HG changeset patch # User Eris Caffee # Date 1368071409 18000 # Node ID e00321d11fe1a547ec759ed3b65e5d6a134049e5 # Parent 1d2b25d4517f41471458a2c4e449d851ddd13b29 to_string simplified. Added Vector constructors from smaller vectors. Added rotation and transform matrix calculation functions. diff -r 1d2b25d4517f -r e00321d11fe1 include/Math.h --- a/include/Math.h Mon May 06 01:06:12 2013 -0500 +++ b/include/Math.h Wed May 08 22:50:09 2013 -0500 @@ -105,7 +105,7 @@ Vector4 vres(0); vres[0] = v[0]*m[0] + v[1]*m[1] + v[2]*m[2] + v[3]*m[3]; vres[1] = v[0]*m[4] + v[1]*m[5] + v[2]*m[6] + v[3]*m[7]; - vres[8] = v[0]*m[8] + v[1]*m[9] + v[2]*m[10] + v[3]*m[11]; + vres[2] = v[0]*m[8] + v[1]*m[9] + v[2]*m[10] + v[3]*m[11]; vres[3] = v[0]*m[12] + v[1]*m[13] + v[2]*m[14] + v[3]*m[15]; v = vres; return v; @@ -133,7 +133,10 @@ ////////////////////////////////////////////////////////////////////////// template - void get_rot_mat33(Matrix33 & m, float rot, Vector3 v); + void get_rot_mat33(Matrix33 & m, float angle, Vector3 v); + + template + void get_transform_mat44(Matrix33 & m, float angle, Vector3 v, Vector3 o); ////////////////////////////////////////////////////////////////////////// @@ -147,20 +150,20 @@ //////////////////////////////////////////////////////////////////////////////// template -void arda::Math::get_rot_mat33(arda::Math::Matrix33 & m, float theta, arda::Math::Vector3 v) +void arda::Math::get_rot_mat33(arda::Math::Matrix33 & m, float angle, arda::Math::Vector3 v) { - m.setidentity(); + // TODO Replace == comparision of floating point number! if (0.0 == v.length()) return; - // TODO: I should also immediately return identity if theta is a multiple of 2*PI but I'm not + // TODO: I should also immediately return identity if angle is a multiple of 2*PI but I'm not // yet sure how I should I check for that (taking into account floating point imprecision). v.normalize(); - float c = cos(theta); - float s = sin(theta); + float c = cos(angle); + float s = sin(angle); float one_minus_c = 1.0f - c; m.assign( @@ -170,4 +173,35 @@ ); } +//////////////////////////////////////////////////////////////////////////////// +template +void arda::Math::get_transform_mat44(arda::Math::Matrix44 & m, + float angle, arda::Math::Vector3 v, + arda::Math::Vector3 p) + { + arda::Math::Matrix33f m33(0); + get_rot_mat33(m33, angle, v); + arda::Math::Vector3f p1 = m33 * p; + + m[0] = m33[0]; + m[1] = m33[1]; + m[2] = m33[2]; + m[3] = 0.0f; + + m[4] = m33[3]; + m[5] = m33[4]; + m[6] = m33[5]; + m[7] = 0.0f; + + m[8] = m33[6]; + m[9] = m33[7]; + m[10] = m33[8]; + m[11] = 0.0f; + + m[12] = p.x - p1.x; + m[13] = p.y - p1.y; + m[14] = p.z - p1.z; + m[15] = 1.0f; + } + #endif diff -r 1d2b25d4517f -r e00321d11fe1 include/Matrix.h --- a/include/Matrix.h Mon May 06 01:06:12 2013 -0500 +++ b/include/Matrix.h Wed May 08 22:50:09 2013 -0500 @@ -236,7 +236,7 @@ return *this; } - std::string & to_string(std::string & s) const; + std::string to_string(void) const; inline Matrix22& setidentity() { @@ -487,7 +487,7 @@ return *this; } - std::string & to_string(std::string & s) const; + std::string to_string(void) const; inline Matrix33& setidentity() { @@ -758,7 +758,7 @@ return *this; } - std::string & to_string(std::string & s) const; + std::string to_string(void) const; inline Matrix44& setidentity() { @@ -891,43 +891,37 @@ // Matrix methods template -std::string & arda::Math::Matrix22::to_string(std::string & s) const +std::string arda::Math::Matrix22::to_string(void) const { - s.clear(); std::stringstream ss; ss << "[ " "[ " << m[0] << ", " << m[1] << " ], " "[ " << m[2] << ", " << m[3] << " ] ]"; - s = ss.str(); - return s; + return ss.str(); } template -std::string & arda::Math::Matrix33::to_string(std::string & s) const +std::string arda::Math::Matrix33::to_string(void) const { - s.clear(); std::stringstream ss; ss << "[ " "[ " << m[0] << ", " << m[1] << ", " << m[2] << " ], " "[ " << m[3] << ", " << m[4] << ", " << m[5] << " ], " "[ " << m[6] << ", " << m[7] << ", " << m[8] << " ], ""]"; - s = ss.str(); - return s; + return ss.str(); } template -std::string & arda::Math::Matrix44::to_string(std::string & s) const +std::string arda::Math::Matrix44::to_string(void) const { - s.clear(); std::stringstream ss; ss << "[ " "[ " << m[0] << ", " << m[1] << ", " << m[2] << ", " << m[3] << " ], " "[ " << m[4] << ", " << m[5] << ", " << m[6] << ", " << m[7] << " ], " "[ " << m[8] << ", " << m[9] << ", " << m[10] << ", " << m[11] << " ], " "[ " << m[12] << ", " << m[13] << ", " << m[14] << ", " << m[15] << " ], ""]"; - s = ss.str(); - return s; + return ss.str(); } #endif // MATRIX_H_ diff -r 1d2b25d4517f -r e00321d11fe1 include/Vector.h --- a/include/Vector.h Mon May 06 01:06:12 2013 -0500 +++ b/include/Vector.h Wed May 08 22:50:09 2013 -0500 @@ -9,512 +9,517 @@ namespace arda - { - namespace Math - { - //////////////////////////////////////////////////////////////////////////////// - // Vectors - // - // Templated classes for 2, 3, and 4 dimensional vectors of any type, - // although these types are really intended to be int, float, and double - // only. (i.e. if you roll your own base type, it had better act like - // a numeric scalar.) - // - // Supported operations on vectors - // - // Construction - // Vector v; // Default zero vector. - // Vector v2(v); // Construct from other vector. - // T a, b; - // Vector v(a, b) // Construct from values. - // [] - // If you have a Vector named v you can access it's member elements as - // v[0], v[1], v[2], and v[3]. in addtion to v.x, v.y, v.z, and v.w - // == != + += - -= - // Defined for operations on two vectors of the same type. - // * *= / /= - // Defined for scalar multiplication/division with int, float, and double. - // * is defined as a standalone template operator for the scalar * Vector form. - // assign(T a, T b [, T b [, T d]]) - // Directly assign values to the vector. - // cross(Vector3& v2) - // cross(Vector3& v2, Vector3& vres) - // Cross product of the vector with v2. Only defined for Vector3 types. - // The version that takes two arguments stores the result in the second - // argument. This may be faster since no temporary object is created - // during the operation. - // dot(Vector& v2) - // The dot product of the vector with v2. - // get_angle(Vector& v2) - // Returns the angle (in radians) between the vector and v2. - // Not meaningful for int vectors. - // get_anglen(Vector& v2) - // Like get_angle(), but the vectors must already be normalized. - // Not meaningful for int vectors. - // to_string(std::string & s) - // Returns a C string representation of the vector. - // This is one of the few non-inline Vector functions. - // length() - // Get the length of a vector. - // Returns a double for all vector types. - // normalize() - // Normalizes the vector. - // Not meaningful for int vectors. - // proj(Vector& v2, Vector& vres) - // Calculates the projection of the vector onto v2 and returns the result - // in vres. - // Not meaningful for int vectors. - // Returns vres. - // - // - // Note that the following typedefs are defined for convenience: - // - // typedef Vector2 Vector2i; - // typedef Vector2 Vector2f; - // typedef Vector2 Vector2d; - // typedef Vector3 Vector3i; - // typedef Vector3 Vector3f; - // typedef Vector3 Vector3d; - // typedef Vector4 Vector4i; - // typedef Vector4 Vector4f; - // typedef Vector4 Vector4d; - // - // - // - // Scalar multiplication and division are overloaded. Why? - // I'm not sure I need this. The idea is to support all likely scalar - // types without having to rely on implicit or explicit type conversion, - // especially not a conversion that might result in loss of precision. - // Multiplying a float Vector by a double scalar, for example. - // - // Is there a better way to do this? Am I worrying about nothing? - // - // - // - // I suppose I could make this into a single Vector template on two parameters - // template class Vector - // { - // T v[N]; - // - // etc... - // - // This might buy perfect generality, but it would come at the expense of - // loops in all of the code, so I don't think it would really be worth it. + { + namespace Math + { + //////////////////////////////////////////////////////////////////////////////// + // Vectors + // + // Templated classes for 2, 3, and 4 dimensional vectors of any type, + // although these types are really intended to be int, float, and double + // only. (i.e. if you roll your own base type, it had better act like + // a numeric scalar.) + // + // Supported operations on vectors + // + // Construction + // Vector v; // Default zero vector. + // Vector v2(v); // Construct from other vector. + // T a, b; + // Vector v(a, b) // Construct from values. + // [] + // If you have a Vector named v you can access it's member elements as + // v[0], v[1], v[2], and v[3]. in addtion to v.x, v.y, v.z, and v.w + // == != + += - -= + // Defined for operations on two vectors of the same type. + // * *= / /= + // Defined for scalar multiplication/division with int, float, and double. + // * is defined as a standalone template operator for the scalar * Vector form. + // assign(T a, T b [, T b [, T d]]) + // Directly assign values to the vector. + // cross(Vector3& v2) + // cross(Vector3& v2, Vector3& vres) + // Cross product of the vector with v2. Only defined for Vector3 types. + // The version that takes two arguments stores the result in the second + // argument. This may be faster since no temporary object is created + // during the operation. + // dot(Vector& v2) + // The dot product of the vector with v2. + // get_angle(Vector& v2) + // Returns the angle (in radians) between the vector and v2. + // Not meaningful for int vectors. + // get_anglen(Vector& v2) + // Like get_angle(), but the vectors must already be normalized. + // Not meaningful for int vectors. + // to_string(std::string & s) + // Returns a C string representation of the vector. + // This is one of the few non-inline Vector functions. + // length() + // Get the length of a vector. + // Returns a double for all vector types. + // normalize() + // Normalizes the vector. + // Not meaningful for int vectors. + // proj(Vector& v2, Vector& vres) + // Calculates the projection of the vector onto v2 and returns the result + // in vres. + // Not meaningful for int vectors. + // Returns vres. + // + // + // Note that the following typedefs are defined for convenience: + // + // typedef Vector2 Vector2i; + // typedef Vector2 Vector2f; + // typedef Vector2 Vector2d; + // typedef Vector3 Vector3i; + // typedef Vector3 Vector3f; + // typedef Vector3 Vector3d; + // typedef Vector4 Vector4i; + // typedef Vector4 Vector4f; + // typedef Vector4 Vector4d; + // + // + // + // Scalar multiplication and division are overloaded. Why? + // I'm not sure I need this. The idea is to support all likely scalar + // types without having to rely on implicit or explicit type conversion, + // especially not a conversion that might result in loss of precision. + // Multiplying a float Vector by a double scalar, for example. + // + // Is there a better way to do this? Am I worrying about nothing? + // + // + // + // I suppose I could make this into a single Vector template on two parameters + // template class Vector + // { + // T v[N]; + // + // etc... + // + // This might buy perfect generality, but it would come at the expense of + // loops in all of the code, so I don't think it would really be worth it. - ///////////////////////////////////////////////////////////////////////////// - template - class Vector2 - { - public: - T x, y; + ///////////////////////////////////////////////////////////////////////////// + template + class Vector2 + { + public: + T x, y; - // Constructors - Vector2() {} - explicit Vector2(T a) : x (a), y(a) {} - Vector2(T a, T b) : x (a), y(b) {} + // Constructors + Vector2() {} + explicit Vector2(T a) : x (a), y(a) {} + Vector2(T a, T b) : x (a), y(b) {} - // Array indexing - inline T& operator[](unsigned int const i) - { assert (i<2); if (i==0) return x; return y; } - inline T operator[](unsigned int const i) const - { assert (i<2); if (i==0) return x; return y; } + // Array indexing + inline T& operator[](unsigned int const i) + { assert (i<2); if (i==0) return x; return y; } + inline T operator[](unsigned int const i) const + { assert (i<2); if (i==0) return x; return y; } - // Assignment - inline Vector2& operator=(Vector2 const & v2) - { x = v2.x; y = v2.y; return *this; } - inline Vector2& assign(T const a, T const b) - { x = a; y = b; return *this; } + // Assignment + inline Vector2& operator=(Vector2 const & v2) + { x = v2.x; y = v2.y; return *this; } + inline Vector2& assign(T const a, T const b) + { x = a; y = b; return *this; } - // Comparison - inline bool operator==(Vector2 const & v2) const - { return ((x == v2.x) && (y == v2.y)); } - inline bool operator!=(Vector2 const & v2) const - { return ! (*this == v2); } + // Comparison + inline bool operator==(Vector2 const & v2) const + { return ((x == v2.x) && (y == v2.y)); } + inline bool operator!=(Vector2 const & v2) const + { return ! (*this == v2); } - // Vector addition - inline Vector2& operator+=(Vector2 const & v2) - { x += v2.x; y += v2.y; return *this; } - inline Vector2 operator+(Vector2 const & v2) const - { return Vector2(*this) += v2; } + // Vector addition + inline Vector2& operator+=(Vector2 const & v2) + { x += v2.x; y += v2.y; return *this; } + inline Vector2 operator+(Vector2 const & v2) const + { return Vector2(*this) += v2; } - // Vector subtraction - inline Vector2& operator-=(Vector2 const & v2) - { x -= v2.x; y -= v2.y; return *this; } - inline Vector2 operator-(Vector2 const & v2) const - { return Vector2(*this) -= v2; } + // Vector subtraction + inline Vector2& operator-=(Vector2 const & v2) + { x -= v2.x; y -= v2.y; return *this; } + inline Vector2 operator-(Vector2 const & v2) const + { return Vector2(*this) -= v2; } - // Scalar multiplication - inline Vector2& operator*=(int const a) - { x *= a; y *= a; return *this; } - inline Vector2& operator*=(float const a) - { x *= a; y *= a; return *this; } - inline Vector2& operator*=(double const a) - { x *= a; y *= a; return *this; } + // Scalar multiplication + inline Vector2& operator*=(int const a) + { x *= a; y *= a; return *this; } + inline Vector2& operator*=(float const a) + { x *= a; y *= a; return *this; } + inline Vector2& operator*=(double const a) + { x *= a; y *= a; return *this; } - inline Vector2 operator*(int const a) const - { return Vector2(*this) *= a;} - inline Vector2 operator*(float const a) const - { return Vector2(*this) *= a;} - inline Vector2 operator*(double const a) const - { return Vector2(*this) *= a;} + inline Vector2 operator*(int const a) const + { return Vector2(*this) *= a;} + inline Vector2 operator*(float const a) const + { return Vector2(*this) *= a;} + inline Vector2 operator*(double const a) const + { return Vector2(*this) *= a;} - // Scalar division - inline Vector2& operator/=(int const a) - { assert(a!=0); x /= a; y /= a; return *this; } - inline Vector2& operator/=(float const a) - { assert(a!=0); x /= a; y /= a; return *this; } - inline Vector2& operator/=(double const a) - { assert(a!=0); x /= a; y /= a; return *this; } + // Scalar division + inline Vector2& operator/=(int const a) + { assert(a!=0); x /= a; y /= a; return *this; } + inline Vector2& operator/=(float const a) + { assert(a!=0); x /= a; y /= a; return *this; } + inline Vector2& operator/=(double const a) + { assert(a!=0); x /= a; y /= a; return *this; } - inline Vector2 operator/(int const a) const - { return Vector2(*this) /= a;} - inline Vector2 operator/(float const a) const - { return Vector2(*this) /= a;} - inline Vector2 operator/(double const a) const - { return Vector2(*this) /= a;} + inline Vector2 operator/(int const a) const + { return Vector2(*this) /= a;} + inline Vector2 operator/(float const a) const + { return Vector2(*this) /= a;} + inline Vector2 operator/(double const a) const + { return Vector2(*this) /= a;} - // methods + // methods - inline T dot(Vector2 const & v2) const - { return x*v2.x + y*v2.y; } + inline T dot(Vector2 const & v2) const + { return x*v2.x + y*v2.y; } - inline double get_angle(Vector2 const & v2) - { - double tmp = dot(v2); - return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2)))); - } + inline double get_angle(Vector2 const & v2) + { + double tmp = dot(v2); + return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2)))); + } - inline double get_anglen(Vector2 const & v2) - { return acos((double) dot(v2)); } + inline double get_anglen(Vector2 const & v2) + { return acos((double) dot(v2)); } - std::string & to_string(std::string & s) const; + std::string to_string(void) const; - inline double length(void) const - { return sqrt((dot(*this))); } + inline double length(void) const + { return sqrt((dot(*this))); } - inline Vector2& normalize() - { - double l = length(); - if (l == 0.0) return *this; - x /= l; y /= l; - return *this; } + inline Vector2& normalize() + { + double l = length(); + if (l == 0.0) return *this; + x /= l; y /= l; + return *this; } - inline Vector2 proj(Vector2 const & v2) - { Vector2 vres; vres = v2 * (dot(v2)/v2.dot(v2)); return vres; } - inline Vector2& proj(Vector2 const & v2, Vector2& vres) - { vres = v2 * dot(v2)/v2.dot(v2); return vres; } - }; + inline Vector2 proj(Vector2 const & v2) + { Vector2 vres; vres = v2 * (dot(v2)/v2.dot(v2)); return vres; } + inline Vector2& proj(Vector2 const & v2, Vector2& vres) + { vres = v2 * dot(v2)/v2.dot(v2); return vres; } + }; - // Scalar multiplication, continued - template - inline Vector2 operator*(int const a, Vector2 const & v) - { return Vector2(v) *= a;} + // Scalar multiplication, continued + template + inline Vector2 operator*(int const a, Vector2 const & v) + { return Vector2(v) *= a;} - template - inline Vector2 operator*(float const a, Vector2 const & v) - { return Vector2(v) *= a;} + template + inline Vector2 operator*(float const a, Vector2 const & v) + { return Vector2(v) *= a;} - template - inline Vector2 operator*(double const a, Vector2 const & v) - { return Vector2(v) *= a;} + template + inline Vector2 operator*(double const a, Vector2 const & v) + { return Vector2(v) *= a;} - ///////////////////////////////////////////////////////////////////////////// - template - class Vector3 - { - public: - T x, y, z; + ///////////////////////////////////////////////////////////////////////////// + template + class Vector3 + { + public: + T x, y, z; - // Constructors - Vector3() {} - explicit Vector3(T a) : x (a), y(a), z(a) {} - Vector3(T a, T b, T c) : x (a), y(b), z(c) {} + // Constructors + Vector3() {} + explicit Vector3(T a) : x (a), y(a), z(a) {} + Vector3(T a, T b, T c) : x (a), y(b), z(c) {} + Vector3(Vector2 v) : x (v.x), y (v.y), z (0) {} - // Array indexing - inline T& operator[](unsigned int const i) - { assert (i<3); if (i==0) return x; if (i==1) return y; return z; } - inline T operator[](unsigned int const i) const - { assert (i<3); if (i==0) return x; if (i==1) return y; return z; } + // Array indexing + inline T& operator[](unsigned int const i) + { assert (i<3); if (i==0) return x; if (i==1) return y; return z; } + inline T operator[](unsigned int const i) const + { assert (i<3); if (i==0) return x; if (i==1) return y; return z; } - // Assignment - inline Vector3& operator=(Vector3 const & v2) - { x = v2.x; y = v2.y; z = v2.z; return *this; } - inline Vector3& assign(T const a, T const b, T const c) - { x = a; y = b; z = c; return *this; } + // Assignment + inline Vector3& operator=(Vector2 const & v2) + { x = v2.x; y = v2.y; z = 0; return *this; } + inline Vector3& operator=(Vector3 const & v2) + { x = v2.x; y = v2.y; z = v2.z; return *this; } - // Comparison - inline bool operator==(Vector3 const & v2) const - { return ((x == v2.x) && (y == v2.y) && (z == v2.z)); } - inline bool operator!=(Vector3 const & v2) const - { return ! (*this == v2); } + inline Vector3& assign(T const a, T const b, T const c) + { x = a; y = b; z = c; return *this; } - // Vector addition - inline Vector3& operator+=(Vector3 const & v2) - { x += v2.x; y += v2.y; z += v2.z; return *this; } - inline Vector3 operator+(Vector3 const & v2) const - { return Vector3(*this) += v2; } + // Comparison + inline bool operator==(Vector3 const & v2) const + { return ((x == v2.x) && (y == v2.y) && (z == v2.z)); } + inline bool operator!=(Vector3 const & v2) const + { return ! (*this == v2); } - // Vector subtraction - inline Vector3& operator-=(Vector3 const & v2) - { x -= v2.x; y -= v2.y; z -= v2.z; return *this; } - inline Vector3 operator-(Vector3 const & v2) const - { return Vector3(*this) -= v2; } + // Vector addition + inline Vector3& operator+=(Vector3 const & v2) + { x += v2.x; y += v2.y; z += v2.z; return *this; } + inline Vector3 operator+(Vector3 const & v2) const + { return Vector3(*this) += v2; } - // Scalar multiplication - inline Vector3& operator*=(int const a) - { x *= a; y *= a; z *= a; return *this; } - inline Vector3& operator*=(float const a) - { x *= a; y *= a; z *= a; return *this; } - inline Vector3& operator*=(double const a) - { x *= a; y *= a; z *= a; return *this; } + // Vector subtraction + inline Vector3& operator-=(Vector3 const & v2) + { x -= v2.x; y -= v2.y; z -= v2.z; return *this; } + inline Vector3 operator-(Vector3 const & v2) const + { return Vector3(*this) -= v2; } - inline Vector3 operator*(int const a) const - { return Vector3(*this) *= a;} - inline Vector3 operator*(float const a) const - { return Vector3(*this) *= a;} - inline Vector3 operator*(double const a) const - { return Vector3(*this) *= a;} + // Scalar multiplication + inline Vector3& operator*=(int const a) + { x *= a; y *= a; z *= a; return *this; } + inline Vector3& operator*=(float const a) + { x *= a; y *= a; z *= a; return *this; } + inline Vector3& operator*=(double const a) + { x *= a; y *= a; z *= a; return *this; } - // Scalar division - inline Vector3& operator/=(int const a) - { assert(a!=0); x /= a; y /= a; z /= a; return *this; } - inline Vector3& operator/=(float const a) - { assert(a!=0); x /= a; y /= a; z /= a; return *this; } - inline Vector3& operator/=(double const a) - { assert(a!=0); x /= a; y /= a; z /= a; return *this; } + inline Vector3 operator*(int const a) const + { return Vector3(*this) *= a;} + inline Vector3 operator*(float const a) const + { return Vector3(*this) *= a;} + inline Vector3 operator*(double const a) const + { return Vector3(*this) *= a;} - inline Vector3 operator/(int const a) const - { return Vector3(*this) /= a;} - inline Vector3 operator/(float const a) const - { return Vector3(*this) /= a;} - inline Vector3 operator/(double const a) const - { return Vector3(*this) /= a;} + // Scalar division + inline Vector3& operator/=(int const a) + { assert(a!=0); x /= a; y /= a; z /= a; return *this; } + inline Vector3& operator/=(float const a) + { assert(a!=0); x /= a; y /= a; z /= a; return *this; } + inline Vector3& operator/=(double const a) + { assert(a!=0); x /= a; y /= a; z /= a; return *this; } + inline Vector3 operator/(int const a) const + { return Vector3(*this) /= a;} + inline Vector3 operator/(float const a) const + { return Vector3(*this) /= a;} + inline Vector3 operator/(double const a) const + { return Vector3(*this) /= a;} - // methods - inline Vector3& cross(Vector3 const & v2, Vector3& vres) - { - vres.x = y*v2.z - v2.y*z; - vres.y = -x*v2.z + v2.x*z; - vres.z = x*v2.y - v2.x*y; - return vres; - } - inline Vector3 cross(Vector3 const & v2) - { - Vector3 vres; - vres.x = y*v2.z - v2.y*z; - vres.y = -x*v2.z + v2.x*z; - vres.z = x*v2.y - v2.x*y; - return vres; - } + // methods - inline T dot(Vector3 const & v2) const - { return x*v2.x + y*v2.y + z*v2.z; } + inline Vector3& cross(Vector3 const & v2, Vector3& vres) + { + vres.x = y*v2.z - v2.y*z; + vres.y = -x*v2.z + v2.x*z; + vres.z = x*v2.y - v2.x*y; + return vres; + } + inline Vector3 cross(Vector3 const & v2) + { + Vector3 vres; + vres.x = y*v2.z - v2.y*z; + vres.y = -x*v2.z + v2.x*z; + vres.z = x*v2.y - v2.x*y; + return vres; + } - inline double get_angle(Vector3 const & v2) - { - double tmp = dot(v2); - return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2)))); - } + inline T dot(Vector3 const & v2) const + { return x*v2.x + y*v2.y + z*v2.z; } - inline double get_anglen(Vector3 const & v2) - { return acos((double) dot(v2)); } + inline double get_angle(Vector3 const & v2) + { + double tmp = dot(v2); + return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2)))); + } - std::string & to_string(std::string & s) const; + inline double get_anglen(Vector3 const & v2) + { return acos((double) dot(v2)); } - inline double length(void) const - { return sqrt((dot(*this))); } + std::string to_string(void) const; - inline Vector3& normalize() - { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; return *this; } + inline double length(void) const + { return sqrt((dot(*this))); } - inline Vector3 proj(Vector3 const & v2) - { Vector3 vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; } - inline Vector3& proj(Vector3 const & v2, Vector3& vres) - { vres = v2 * dot(v2)/v2.dot(v2); return vres; } - }; + inline Vector3& normalize() + { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; return *this; } - // Scalar multiplication, continued - template - inline Vector3 operator*(int const a, Vector3 const & v) - { return Vector3(v) *= a;} + inline Vector3 proj(Vector3 const & v2) + { Vector3 vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; } + inline Vector3& proj(Vector3 const & v2, Vector3& vres) + { vres = v2 * dot(v2)/v2.dot(v2); return vres; } + }; + + // Scalar multiplication, continued + template + inline Vector3 operator*(int const a, Vector3 const & v) + { return Vector3(v) *= a;} - template - inline Vector3 operator*(float const a, Vector3 const & v) - { return Vector3(v) *= a;} + template + inline Vector3 operator*(float const a, Vector3 const & v) + { return Vector3(v) *= a;} - template - inline Vector3 operator*(double const a, Vector3 const & v) - { return Vector3(v) *= a;} + template + inline Vector3 operator*(double const a, Vector3 const & v) + { return Vector3(v) *= a;} - ///////////////////////////////////////////////////////////////////////////// - template - class Vector4 - { - public: - T x, y, z, w; + ///////////////////////////////////////////////////////////////////////////// + template + class Vector4 + { + public: + T x, y, z, w; - // Constructors - Vector4() {} - explicit Vector4(T a) : x (a), y(a), z(a), w(a) {} - Vector4(T a, T b, T c, T d) : x (a), y(b), z(c), w(d) {} + // Constructors + Vector4() {} + explicit Vector4(T a) : x (a), y(a), z(a), w(a) {} + Vector4(T a, T b, T c, T d) : x (a), y(b), z(c), w(d) {} + Vector4(Vector2 v) : x (v.x), y (v.y), z (0), w (0) {} + Vector4(Vector3 v) : x (v.x), y (v.y), z (v.z), w (0) {} - // Array indexing - inline T& operator[](unsigned int const i) - { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; } - inline T operator[](unsigned int const i) const - { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; } + // Array indexing + inline T& operator[](unsigned int const i) + { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; } + inline T operator[](unsigned int const i) const + { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; } - // Assignment - inline Vector4& operator=(Vector4 const & v2) - { x = v2.x; y = v2.y; z = v2.z; w = v2.w; return *this; } - inline Vector4& assign(T const a, T const b, T const c, T const d) - { x = a; y = b; z = c; w = d; return *this; } + // Assignment + inline Vector4& operator=(Vector2 const & v2) + { x = v2.x; y = v2.y; z = 0; w = 0; return *this; } + inline Vector4& operator=(Vector3 const & v2) + { x = v2.x; y = v2.y; z = v2.z; w = 0; return *this; } + inline Vector4& operator=(Vector4 const & v2) + { x = v2.x; y = v2.y; z = v2.z; w = v2.w; return *this; } - // Comparison - inline bool operator==(Vector4 const & v2) const - { return ((x == v2.x) && (y == v2.y) && (z == v2.z) && (w == v2.w)); } - inline bool operator!=(Vector4 const & v2) const - { return ! (*this == v2); } + inline Vector4& assign(T const a, T const b, T const c, T const d) + { x = a; y = b; z = c; w = d; return *this; } - // Vector addition - inline Vector4& operator+=(Vector4 const & v2) - { x += v2.x; y += v2.y; z += v2.z; w += v2.w; return *this; } - inline Vector4 operator+(Vector4 const & v2) const - { return Vector4(*this) += v2; } + // Comparison + inline bool operator==(Vector4 const & v2) const + { return ((x == v2.x) && (y == v2.y) && (z == v2.z) && (w == v2.w)); } + inline bool operator!=(Vector4 const & v2) const + { return ! (*this == v2); } - // Vector subtraction - inline Vector4& operator-=(Vector4 const & v2) - { x -= v2.x; y -= v2.y; z -= v2.z; w -= v2.w; return *this; } - inline Vector4 operator-(Vector4 const & v2) const - { return Vector4(*this) -= v2; } + // Vector addition + inline Vector4& operator+=(Vector4 const & v2) + { x += v2.x; y += v2.y; z += v2.z; w += v2.w; return *this; } + inline Vector4 operator+(Vector4 const & v2) const + { return Vector4(*this) += v2; } - // Scalar multiplication - inline Vector4& operator*=(int const a) - { x *= a; y *= a; z *= a; w *= a; return *this; } - inline Vector4& operator*=(float const a) - { x *= a; y *= a; z *= a; w *= a; return *this; } - inline Vector4& operator*=(double const a) - { x *= a; y *= a; z *= a; w *= a; return *this; } + // Vector subtraction + inline Vector4& operator-=(Vector4 const & v2) + { x -= v2.x; y -= v2.y; z -= v2.z; w -= v2.w; return *this; } + inline Vector4 operator-(Vector4 const & v2) const + { return Vector4(*this) -= v2; } - inline Vector4 operator*(int const a) const - { return Vector4(*this) *= a;} - inline Vector4 operator*(float const a) const - { return Vector4(*this) *= a;} - inline Vector4 operator*(double const a) const - { return Vector4(*this) *= a;} + // Scalar multiplication + inline Vector4& operator*=(int const a) + { x *= a; y *= a; z *= a; w *= a; return *this; } + inline Vector4& operator*=(float const a) + { x *= a; y *= a; z *= a; w *= a; return *this; } + inline Vector4& operator*=(double const a) + { x *= a; y *= a; z *= a; w *= a; return *this; } - // Scalar division - inline Vector4& operator/=(int const a) - { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; } - inline Vector4& operator/=(float const a) - { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; } - inline Vector4& operator/=(double const a) - { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; } + inline Vector4 operator*(int const a) const + { return Vector4(*this) *= a;} + inline Vector4 operator*(float const a) const + { return Vector4(*this) *= a;} + inline Vector4 operator*(double const a) const + { return Vector4(*this) *= a;} - inline Vector4 operator/(int const a) const - { return Vector4(*this) /= a;} - inline Vector4 operator/(float const a) const - { return Vector4(*this) /= a;} - inline Vector4 operator/(double const a) const - { return Vector4(*this) /= a;} + // Scalar division + inline Vector4& operator/=(int const a) + { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; } + inline Vector4& operator/=(float const a) + { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; } + inline Vector4& operator/=(double const a) + { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; } + inline Vector4 operator/(int const a) const + { return Vector4(*this) /= a;} + inline Vector4 operator/(float const a) const + { return Vector4(*this) /= a;} + inline Vector4 operator/(double const a) const + { return Vector4(*this) /= a;} - // methods - inline T dot(Vector4 const & v2) const - { return x*v2.x + y*v2.y + z*v2.z + w*v2.w; } + // methods - inline double get_angle(Vector4 const & v2) - { - double tmp = dot(v2); - return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2)))); - } + inline T dot(Vector4 const & v2) const + { return x*v2.x + y*v2.y + z*v2.z + w*v2.w; } - inline double get_anglen(Vector4 const & v2) - { return acos((double) dot(v2)); } + inline double get_angle(Vector4 const & v2) + { + double tmp = dot(v2); + return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2)))); + } - std::string & to_string(std::string & s) const; + inline double get_anglen(Vector4 const & v2) + { return acos((double) dot(v2)); } - inline double length(void) const - { return sqrt((dot(*this))); } + std::string to_string(void) const; - inline Vector4& normalize() - { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; w /= l; return *this; } + inline double length(void) const + { return sqrt((dot(*this))); } - inline Vector4 proj(Vector4 const & v2) - { Vector4 vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; } - inline Vector4& proj(Vector4 const & v2, Vector4& vres) - { vres = v2 * dot(v2)/v2.dot(v2); return vres; } - }; + inline Vector4& normalize() + { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; w /= l; return *this; } - // Scalar multiplication, continued - template - inline Vector4 operator*(int const a, Vector4 const & v) - { return Vector4(v) *= a;} + inline Vector4 proj(Vector4 const & v2) + { Vector4 vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; } + inline Vector4& proj(Vector4 const & v2, Vector4& vres) + { vres = v2 * dot(v2)/v2.dot(v2); return vres; } + }; + + // Scalar multiplication, continued + template + inline Vector4 operator*(int const a, Vector4 const & v) + { return Vector4(v) *= a;} - template - inline Vector4 operator*(float const a, Vector4 const & v) - { return Vector4(v) *= a;} + template + inline Vector4 operator*(float const a, Vector4 const & v) + { return Vector4(v) *= a;} - template - inline Vector4 operator*(double const a, Vector4 const & v) - { return Vector4(v) *= a;} + template + inline Vector4 operator*(double const a, Vector4 const & v) + { return Vector4(v) *= a;} - ///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// - typedef Vector2 Vector2i; - typedef Vector2 Vector2f; - typedef Vector2 Vector2d; + typedef Vector2 Vector2i; + typedef Vector2 Vector2f; + typedef Vector2 Vector2d; - typedef Vector3 Vector3i; - typedef Vector3 Vector3f; - typedef Vector3 Vector3d; + typedef Vector3 Vector3i; + typedef Vector3 Vector3f; + typedef Vector3 Vector3d; - typedef Vector4 Vector4i; - typedef Vector4 Vector4f; - typedef Vector4 Vector4d; + typedef Vector4 Vector4i; + typedef Vector4 Vector4f; + typedef Vector4 Vector4d; - } // namespace Math + } // namespace Math - } // namespace arda + } // namespace arda //////////////////////////////////////////////////////////////////////////////// template -std::string & arda::Math::Vector2::to_string(std::string & s) const - { - s.clear(); - std::stringstream ss; - ss << "[ " << x << ", " << y << " ]"; - s = ss.str(); - return s; - } +std::string arda::Math::Vector2::to_string(void) const + { + std::stringstream ss; + ss << "[ " << x << ", " << y << " ]"; + return ss.str(); + } //////////////////////////////////////////////////////////////////////////////// template -std::string & arda::Math::Vector3::to_string(std::string & s) const - { - s.clear(); - std::stringstream ss; - ss << "[ " << x << ", " << y << ", " << z << " ]"; - s = ss.str(); - return s; - } +std::string arda::Math::Vector3::to_string(void) const + { + std::stringstream ss; + ss << "[ " << x << ", " << y << ", " << z << " ]"; + return ss.str(); + } //////////////////////////////////////////////////////////////////////////////// template -std::string & arda::Math::Vector4::to_string(std::string & s) const - { - s.clear(); - std::stringstream ss; - ss << "[ " << x << ", " << y << ", " << z << ", " << w << " ]"; - s = ss.str(); - return s; - } +std::string arda::Math::Vector4::to_string(void) const + { + std::stringstream ss; + ss << "[ " << x << ", " << y << ", " << z << ", " << w << " ]"; + return ss.str(); + } #endif // VECTOR_H_