hypertile.cpp | vector.cpp | ||
hypertile.h | vector.h |
#ifndef VECTOR_H #define VECTOR_H #include <stdlib.h> #include <math.h> // **************************** // Two-Dimensional Vector Class // **************************** class vec3; class vec2 { public: float x, y; inline vec2(void) {} inline vec2(float _x, float _y) { x = _x, y = _y; } inline vec2(float theta) { x = (float)cos(theta), y = (float)sin(theta); } inline void zero(void) { x = y = 0.f; } inline int operator ==(const vec2& a) const { return x == a.x && y == a.y; } inline int operator !=(const vec2& a) const { return x != a.x || y != a.y; } inline vec2 operator +(const vec2& a) const { return vec2(x + a.x, y + a.y); } inline vec2 operator -(const vec2& a) const { return vec2(x - a.x, y - a.y); } inline float operator *(const vec2& a) const { return x*a.x + y*a.y; } inline vec2 operator *(const float a) const { return vec2(x*a, y*a); } inline vec2 operator /(const float a) const { return (*this) * (1.f / a); } inline float operator ^(const vec2& a) const { return y*a.x - x*a.y; } inline const vec2& operator +=(const vec2& a) { (*this) = (*this) + a; return (*this); } inline const vec2& operator -=(const vec2& a) { (*this) = (*this) - a; return (*this); } inline const vec2& operator *=(const float a) { (*this) = (*this) * a; return (*this); } inline const vec2& operator /=(const float a) { (*this) = (*this) / a; return (*this); } inline float operator [](int i) const { return ((float*)this)[i]; } inline float& operator [](int i) { return ((float*)this)[i]; } inline float len(void) const { return (float)sqrt(x*x + y*y); } inline vec2 normalized(void) const { return (*this) / len(); } inline void normalize(void) { (*this) /= len(); } inline vec2 hklein2poincare(void) const { float q = (float)sqrt(1.f - x*x - y*y); return (*this) / (1.f + q); } inline vec2 hpoincare2klein(void) const { float q = 2.f / (1.f + x*x + y*y); return (*this) * q; } inline const vec2& operator =(const vec3& a); static vec2 hmidpoint(vec2& p1, vec2& p2); // note: "static" refers to lack of "this" }; // ****************************** // Three-Dimensional Vector Class // ****************************** class vec3 { public: float x, y, z; inline vec3(void) {} inline vec3(float _x, float _y, float _z) { x = _x, y = _y, z = _z; } inline void zero(void) { x = y = z = 0.f; } inline int operator ==(const vec3& a) const { return x == a.x && y == a.y && z == a.z; } inline int operator !=(const vec3& a) const { return x != a.x || y != a.y || z != a.z; } inline vec3 operator +(const vec3& a) const { return vec3(x + a.x, y + a.y, z + a.z); } inline vec3 operator -(const vec3& a) const { return vec3(x - a.x, y - a.y, z - a.z); } inline float operator *(const vec3& a) const { return x*a.x + y*a.y + z*a.z; } inline float operator *(const vec2& a) const { return x*a.x + y*a.y + z; } inline vec3 operator *(const float a) const { return vec3(x*a, y*a, z*a); } inline vec3 operator /(const float a) const { return (*this) * (1.f / a); } inline vec3 operator ^(const vec3& a) const { return vec3(y*a.z - z*a.y, z*a.x - x*a.z, x*a.y - y*a.x); } inline const vec3& operator +=(const vec3& a) { (*this) = (*this) + a; return (*this); } inline const vec3& operator -=(const vec3& a) { (*this) = (*this) - a; return (*this); } inline const vec3& operator *=(const float a) { (*this) = (*this) * a; return (*this); } inline const vec3& operator /=(const float a) { (*this) = (*this) / a; return (*this); } inline const vec3& operator ^=(const vec3& a) { (*this) = (*this) ^ a; return (*this); } inline float operator [](int i) const { return ((float*)this)[i]; } inline float& operator [](int i) { return ((float*)this)[i]; } inline float len(void) const { return (float)sqrt(x*x + y*y + z*z); } inline vec3 normalized(void) const { return (*this) / len(); } inline void normalize(void) { (*this) /= len(); } inline vec3 hklein2poincare(void) const { float q = (float)sqrt(1.f - x*x - y*y - z*z); return (*this) / (1.f + q); } inline vec3 hpoincare2klein(void) const { float q = 2.f / (1.f + x*x + y*y + z*z); return (*this) * q; } static vec3 random(void) { float x = (float)((rand()*rand()) & 0x7FFF) / 32767.f; float y = (float)((rand()^rand()) & 0x7FFF) / 32767.f; float z = (float)((rand()+rand()) & 0x7FFF) / 32767.f; return vec3(x, y, z); } inline void operator =(const vec2& a) { (*this) = vec3(a.x, a.y, 1.f); } static vec3 hmidpoint(vec3& p1, vec3& p2); // note: "static" refers to lack of "this" }; inline const vec2& vec2::operator =(const vec3& a) { (*this) = vec2(a.x, a.y) / a.z; } // **************************** // Two-Dimensional Matrix Class // **************************** struct mat2 { public: vec2 x, y; inline mat2(void) {} inline mat2(float m11, float m12, float m21, float m22) { x = vec2(m11, m12); y = vec2(m21, m22); } inline mat2(const vec2& mx, const vec2& my) { x = mx, y = my; } inline void identity(void) { x = vec2(1.f, 0.f); y = vec2(0.f, 1.f); } inline const int operator ==(const mat2& a) const { return x == a.x && y == a.y; } inline const int operator !=(const mat2& a) const { return x != a.x || y != a.y; } inline mat2 operator +(const mat2& a) const { return mat2(x + a.x, y + a.y); } inline mat2 operator -(const mat2& a) const { return mat2(x - a.x, y - a.y); } inline mat2 operator *(const mat2& a) const { mat2 tmp = a.transposed(); return mat2(tmp*x, tmp*y); } inline vec2 operator *(const vec2& a) const { return vec2(x*a, y*a); } inline mat2 operator *(const float a) const { return mat2(x*a, y*a); } inline mat2 operator /(const float a) const { return (*this) * (1.f / a); } inline const mat2& operator +=(const mat2& a) { (*this) = (*this) + a; return (*this); } inline const mat2& operator -=(const mat2& a) { (*this) = (*this) - a; return (*this); } inline const mat2& operator *=(const mat2& a) { (*this) = (*this) * a; return (*this); } inline const mat2& operator *=(const float a) { (*this) = (*this) * a; return (*this); } inline const mat2& operator /=(const float a) { (*this) = (*this) / a; return (*this); } inline const vec2& operator [](int i) const { return ((vec2*)this)[i]; } inline vec2& operator [](int i) { return ((vec2*)this)[i]; } inline float det(void) const { ; } inline mat2 transposed(void) const { return mat2(x.x, y.x, x.y, y.y); } inline void transpose(void) { (*this) = mat2(x.x, y.x, x.y, y.y); } inline mat2 inverse(void) const { ; } inline mat2 invert(void) { ; } static mat2 rot(float theta) { // Same as constructor mat2(theta) float c = (float)cos(theta); float s = (float)sin(theta); return mat2(c, s, -s, c); } }; // ****************************** // Three-Dimensional Matrix Class // ****************************** struct mat3 { public: vec3 x, y, z; inline mat3(void) {} inline mat3(float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33) { x = vec3(m11, m12, m13); y = vec3(m21, m22, m23); z = vec3(m31, m32, m33); } inline mat3(const vec3& mx, const vec3& my, const vec3& mz) { x = mx, y = my, z = mz; } inline void identity(void) { x = vec3(1.f, 0.f, 0.f); y = vec3(0.f, 1.f, 0.f); z = vec3(0.f, 0.f, 1.f); } inline const int operator ==(const mat3& a) const { return x == a.x && y == a.y && z == a.z; } inline const int operator !=(const mat3& a) const { return x != a.x || y != a.y || z != a.z; } inline mat3 operator +(const mat3& a) const { return mat3(x + a.x, y + a.y, z + a.z); } inline mat3 operator -(const mat3& a) const { return mat3(x - a.x, y - a.y, z - a.z); } inline mat3 operator *(const mat3& a) const { mat3 tmp = a.transposed(); return mat3(tmp*x, tmp*y, tmp*z); } inline vec3 operator *(const vec3& a) const { return vec3(x*a, y*a, z*a); } inline vec2 operator *(const vec2& a) const { return vec2(x*a, y*a) / (z*a); } inline mat3 operator *(const float a) const { return mat3(x*a, y*a, z*a); } inline mat3 operator /(const float a) const { return (*this) * (1.f / a); } inline const mat3& operator +=(const mat3& a) { (*this) = (*this) + a; return (*this); } inline const mat3& operator -=(const mat3& a) { (*this) = (*this) - a; return (*this); } inline const mat3& operator *=(const mat3& a) { (*this) = (*this) * a; return (*this); } inline const mat3& operator *=(const float a) { (*this) = (*this) * a; return (*this); } inline const mat3& operator /=(const float a) { (*this) = (*this) / a; return (*this); } inline const vec3& operator [](int i) const { return ((vec3*)this)[i]; } inline vec3& operator [](int i) { return ((vec3*)this)[i]; } inline float det(void) const { return x.y*y.z*z.x - x.z*y.y*z.x + x.z*y.x*z.y + x.x*y.y*z.z - x.x*y.z*z.y - x.y*y.x*z.z ; } inline mat3 transposed(void) const { return mat3(x.x, y.x, z.x, x.y, y.y, z.y, x.z, y.z, z.z); } inline void transpose(void) { (*this) = mat3(x.x, y.x, z.x, x.y, y.y, z.y, x.z, y.z, z.z); } inline mat3 inverse(void) const { float d = (*this).det(); return mat3(y.y*z.z - y.z*z.y, x.z*z.y - x.y*z.z, x.y*y.z - x.z*y.y, y.z*z.x - y.x*z.z, x.x*z.z - x.z*z.x, x.z*y.x - x.x*y.z, y.x*z.y - y.y*z.x, x.y*z.x - x.x*z.y, x.x*y.y - x.y*y.x) / d; } inline void invert(void) { float d = (*this).det(); (*this) = mat3(y.y*z.z - y.z*z.y, x.z*z.y - x.y*z.z, x.y*y.z - x.z*y.y, y.z*z.x - y.x*z.z, x.x*z.z - x.z*z.x, x.z*y.x - x.x*y.z, y.x*z.y - y.y*z.x, x.y*z.x - x.x*z.y, x.x*y.y - x.y*y.x) / d; } static mat3 hrotate(vec2& p, float theta); // note: "static" refers to lack of "this" static mat3 htranslate(vec2& p); // note: "static" refers to lack of "this" static mat3 hntranslate(vec2& p); // note: "static" refers to lack of "this" static mat3 rotX(float theta) { float c = (float)cos(theta); float s = (float)sin(theta); return mat3(1.f, 0.f, 0.f, 0.f, c, s, 0.f, -s, c); } static mat3 rotY(float theta) { float c = (float)cos(theta); float s = (float)sin(theta); return mat3(c, 0.f, -s, 0.f, 1.f, 0.f, s, 0.f, c); } static mat3 rotZ(float theta) { float c = (float)cos(theta); float s = (float)sin(theta); return mat3(c, s, 0.f, -s, c, 0.f, 0.f, 0.f, 1.f); } static mat3 ypr(float yaw, float pitch, float roll) { float cy = (float)cos(yaw); float sy = (float)sin(yaw); float cp = (float)cos(pitch); float sp = (float)sin(pitch); float cr = (float)cos(roll); float sr = (float)sin(roll); return mat3(sp*sr*sy + cr*cy, cp*sr, cy*sp*sr - cr*sy, cr*sp*sy - cy*sr, cp*cr, cr*cy*sp + sr*sy, cp*sy, - sp, cp*cy); } static mat3 horthogonalized(mat3 &m) { // Decomposes a hyperbolic matrix into a translation and a // rotation, and reconstructs the matrix. This process // removes accumulative denormalization of the matrix. vec2 p = vec2(m.x.z, m.y.z) / m.z.z; vec2 q = vec2(m.x.x+m.x.z, m.y.x+m.y.z) / (m.z.x+m.z.z); mat3 t = hntranslate(p); q = t*q; t.x.z = t.z.x = -t.x.z; // invert translation t.y.z = t.z.y = -t.y.z; return t * rotZ(-(float)atan2(q.y, q.x)); } static mat3 htransline(vec2 &c1, vec2 &v1, vec2 &c2, vec2 &v2) { // Computes a matrix which takes one line segment (c1,v1) // to another (c2,v2). The line segments must be congruent. mat3 t1 = hntranslate(c1); mat3 t2 = hntranslate(c2); float a1 = (float)atan2(t1.y*v1, t1.x*v1); float a2 = (float)atan2(t2.y*v2, t2.x*v2); t2.x.z = t2.z.x = -t2.x.z; // invert translation t2.y.z = t2.z.y = -t2.y.z; return t2 * rotZ(a1 - a2) * t1; } static void hdecompose(float &theta, vec2 &transl, mat3 &m) { // Decomposes a matrix (m) into a rotation followed by a // translation. // Working?!? vec2 q = vec2(m.x.x+m.x.z, m.y.x+m.y.z) / (m.z.x+m.z.z); transl = vec2(m.x.z, m.y.z) / m.z.z; q = htranslate(transl)*q; transl.x = -transl.x; transl.y = -transl.y; theta = -(float)atan2(q.y, q.x); } static mat3 hinterpolate(mat3 &m1, mat3 &m2, float factor) { // Decomposes two matrices and interpolates between them. // Working?!? float a1, a2; vec2 t1, t2; hdecompose(a1, t1, m1); hdecompose(a2, t2, m2); a1 += (a2 - a1)*factor; t1 += (t2 - t1)*factor; return htranslate(t1)*rotZ(a1); } }; #endif
This page © Bernie Freidin, 2000.