geometry.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #ifndef __GEOMETRY_H__
  2. #define __GEOMETRY_H__
  3. #include <cmath>
  4. #include <cassert>
  5. #include <stdlib.h>
  6. template<size_t DimCols,size_t DimRows,typename T> class mat;
  7. template <size_t DIM, typename T> struct vec {
  8. vec() { for (size_t i=DIM; i--; data_[i] = T()); }
  9. T& operator[](const size_t i) { assert(i<DIM); return data_[i]; }
  10. const T& operator[](const size_t i) const { assert(i<DIM); return data_[i]; }
  11. private:
  12. T data_[DIM];
  13. };
  14. /////////////////////////////////////////////////////////////////////////////////
  15. template <typename T> struct vec<2,T> {
  16. vec() : x(T()), y(T()) {}
  17. vec(T X, T Y) : x(X), y(Y) {}
  18. template <class U> vec<2,T>(const vec<2,U> &v);
  19. T& operator[](const size_t i) { assert(i<2); return i<=0 ? x : y; }
  20. const T& operator[](const size_t i) const { assert(i<2); return i<=0 ? x : y; }
  21. T x,y;
  22. };
  23. /////////////////////////////////////////////////////////////////////////////////
  24. template <typename T> struct vec<3,T> {
  25. vec() : x(T()), y(T()), z(T()) {}
  26. vec(T X, T Y, T Z) : x(X), y(Y), z(Z) {}
  27. template <class U> vec<3,T>(const vec<3,U> &v);
  28. T& operator[](const size_t i) { assert(i<3); return i<=0 ? x : (1==i ? y : z); }
  29. const T& operator[](const size_t i) const { assert(i<3); return i<=0 ? x : (1==i ? y : z); }
  30. float norm() { return std::sqrt(x*x+y*y+z*z); }
  31. vec<3,T> & normalize(T l=1) { *this = (*this)*(l/norm()); return *this; }
  32. T x,y,z;
  33. };
  34. /////////////////////////////////////////////////////////////////////////////////
  35. template<size_t DIM,typename T> T operator*(const vec<DIM,T>& lhs, const vec<DIM,T>& rhs) {
  36. T ret = T();
  37. for (size_t i=DIM; i--; ret+=lhs[i]*rhs[i]);
  38. return ret;
  39. }
  40. template<size_t DIM,typename T>vec<DIM,T> operator+(vec<DIM,T> lhs, const vec<DIM,T>& rhs) {
  41. for (size_t i=DIM; i--; lhs[i]+=rhs[i]);
  42. return lhs;
  43. }
  44. template<size_t DIM,typename T>vec<DIM,T> operator-(vec<DIM,T> lhs, const vec<DIM,T>& rhs) {
  45. for (size_t i=DIM; i--; lhs[i]-=rhs[i]);
  46. return lhs;
  47. }
  48. template<size_t DIM,typename T,typename U> vec<DIM,T> operator*(vec<DIM,T> lhs, const U& rhs) {
  49. for (size_t i=DIM; i--; lhs[i]*=rhs);
  50. return lhs;
  51. }
  52. template<size_t DIM,typename T,typename U> vec<DIM,T> operator/(vec<DIM,T> lhs, const U& rhs) {
  53. for (size_t i=DIM; i--; lhs[i]/=rhs);
  54. return lhs;
  55. }
  56. template<size_t LEN,size_t DIM,typename T> vec<LEN,T> embed(const vec<DIM,T> &v, T fill=1) {
  57. vec<LEN,T> ret;
  58. for (size_t i=LEN; i--; ret[i]=(i<DIM?v[i]:fill));
  59. return ret;
  60. }
  61. template<size_t LEN,size_t DIM, typename T> vec<LEN,T> proj(const vec<DIM,T> &v) {
  62. vec<LEN,T> ret;
  63. for (size_t i=LEN; i--; ret[i]=v[i]);
  64. return ret;
  65. }
  66. template <typename T> vec<3,T> cross(vec<3,T> v1, vec<3,T> v2) {
  67. return vec<3,T>(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
  68. }
  69. #if 0
  70. template <size_t DIM, typename T> std::ostream& operator<<(std::ostream& out, vec<DIM,T>& v) {
  71. for(unsigned int i=0; i<DIM; i++) {
  72. out << v[i] << " " ;
  73. }
  74. return out ;
  75. }
  76. #endif
  77. /////////////////////////////////////////////////////////////////////////////////
  78. template<size_t DIM,typename T> struct dt {
  79. static T det(const mat<DIM,DIM,T>& src) {
  80. T ret=0;
  81. for (size_t i=DIM; i--; ret += src[0][i]*src.cofactor(0,i));
  82. return ret;
  83. }
  84. };
  85. template<typename T> struct dt<1,T> {
  86. static T det(const mat<1,1,T>& src) {
  87. return src[0][0];
  88. }
  89. };
  90. /////////////////////////////////////////////////////////////////////////////////
  91. template<size_t DimRows,size_t DimCols,typename T> class mat {
  92. vec<DimCols,T> rows[DimRows];
  93. public:
  94. mat() {}
  95. vec<DimCols,T>& operator[] (const size_t idx) {
  96. assert(idx<DimRows);
  97. return rows[idx];
  98. }
  99. const vec<DimCols,T>& operator[] (const size_t idx) const {
  100. assert(idx<DimRows);
  101. return rows[idx];
  102. }
  103. vec<DimRows,T> col(const size_t idx) const {
  104. assert(idx<DimCols);
  105. vec<DimRows,T> ret;
  106. for (size_t i=DimRows; i--; ret[i]=rows[i][idx]);
  107. return ret;
  108. }
  109. void set_col(size_t idx, vec<DimRows,T> v) {
  110. assert(idx<DimCols);
  111. for (size_t i=DimRows; i--; rows[i][idx]=v[i]);
  112. }
  113. static mat<DimRows,DimCols,T> identity() {
  114. mat<DimRows,DimCols,T> ret;
  115. for (size_t i=DimRows; i--; )
  116. for (size_t j=DimCols;j--; ret[i][j]=(i==j));
  117. return ret;
  118. }
  119. T det() const {
  120. return dt<DimCols,T>::det(*this);
  121. }
  122. mat<DimRows-1,DimCols-1,T> get_minor(size_t row, size_t col) const {
  123. mat<DimRows-1,DimCols-1,T> ret;
  124. for (size_t i=DimRows-1; i--; )
  125. for (size_t j=DimCols-1;j--; ret[i][j]=rows[i<row?i:i+1][j<col?j:j+1]);
  126. return ret;
  127. }
  128. T cofactor(size_t row, size_t col) const {
  129. return get_minor(row,col).det()*((row+col)%2 ? -1 : 1);
  130. }
  131. mat<DimRows,DimCols,T> adjugate() const {
  132. mat<DimRows,DimCols,T> ret;
  133. for (size_t i=DimRows; i--; )
  134. for (size_t j=DimCols; j--; ret[i][j]=cofactor(i,j));
  135. return ret;
  136. }
  137. mat<DimRows,DimCols,T> invert_transpose() {
  138. mat<DimRows,DimCols,T> ret = adjugate();
  139. T tmp = ret[0]*rows[0];
  140. return ret/tmp;
  141. }
  142. mat<DimRows,DimCols,T> invert() {
  143. return invert_transpose().transpose();
  144. }
  145. mat<DimCols,DimRows,T> transpose() {
  146. mat<DimCols,DimRows,T> ret;
  147. for (size_t i=DimCols; i--; ret[i]=this->col(i));
  148. return ret;
  149. }
  150. };
  151. /////////////////////////////////////////////////////////////////////////////////
  152. template<size_t DimRows,size_t DimCols,typename T> vec<DimRows,T> operator*(const mat<DimRows,DimCols,T>& lhs, const vec<DimCols,T>& rhs) {
  153. vec<DimRows,T> ret;
  154. for (size_t i=DimRows; i--; ret[i]=lhs[i]*rhs);
  155. return ret;
  156. }
  157. template<size_t R1,size_t C1,size_t C2,typename T>mat<R1,C2,T> operator*(const mat<R1,C1,T>& lhs, const mat<C1,C2,T>& rhs) {
  158. mat<R1,C2,T> result;
  159. for (size_t i=R1; i--; )
  160. for (size_t j=C2; j--; result[i][j]=lhs[i]*rhs.col(j));
  161. return result;
  162. }
  163. template<size_t DimRows,size_t DimCols,typename T>mat<DimCols,DimRows,T> operator/(mat<DimRows,DimCols,T> lhs, const T& rhs) {
  164. for (size_t i=DimRows; i--; lhs[i]=lhs[i]/rhs);
  165. return lhs;
  166. }
  167. #if 0
  168. template <size_t DimRows,size_t DimCols,class T> std::ostream& operator<<(std::ostream& out, mat<DimRows,DimCols,T>& m) {
  169. for (size_t i=0; i<DimRows; i++) out << m[i] << std::endl;
  170. return out;
  171. }
  172. #endif
  173. /////////////////////////////////////////////////////////////////////////////////
  174. typedef vec<2, float> Vec2f;
  175. typedef vec<2, int> Vec2i;
  176. typedef vec<3, float> Vec3f;
  177. typedef vec<3, int> Vec3i;
  178. typedef vec<4, float> Vec4f;
  179. typedef mat<4,4,float> Matrix;
  180. #endif //__GEOMETRY_H__