PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/wykobi_matrix.inl

http://wykobi.codeplex.com
C++ Header | 313 lines | 262 code | 33 blank | 18 comment | 17 complexity | ea7b5ea6f57ba790dc510fe430feea3f MD5 | raw file
  1. /*
  2. (***********************************************************************)
  3. (* *)
  4. (* Wykobi Computational Geometry Library *)
  5. (* Release Version 0.0.4 *)
  6. (* http://www.wykobi.com *)
  7. (* Copyright (c) 2005-2009 Arash Partow, All Rights Reserved. *)
  8. (* *)
  9. (* The Wykobi computational geometry library and its components are *)
  10. (* supplied under the terms of the General Wykobi License agreement. *)
  11. (* The contents of the Wykobi computational geometry library and its *)
  12. (* components may not be copied or disclosed except in accordance with *)
  13. (* the terms of that agreement. *)
  14. (* *)
  15. (* URL: http://www.wykobi.com/license.html *)
  16. (* *)
  17. (***********************************************************************)
  18. */
  19. #include "wykobi.hpp"
  20. #include "wykobi_matrix.hpp"
  21. #include <algorithm>
  22. namespace wykobi
  23. {
  24. template<typename T, std::size_t M, std::size_t N>
  25. inline matrix<T,M,N>::matrix(const matrix<T,M,N>& m)
  26. : dptr(reinterpret_cast<T*>(&data))
  27. {
  28. std::copy(m.dptr,m.dptr + (M * N), dptr);
  29. }
  30. template<typename T, std::size_t M, std::size_t N>
  31. inline matrix<T,M,N>& matrix<T,M,N>::operator=(const matrix<T,M,N>& m)
  32. {
  33. if (this == &m)
  34. return *this;
  35. std::copy(m.dptr,m.dptr + (M * N), dptr);
  36. return *this;
  37. }
  38. template<typename T, std::size_t M, std::size_t N>
  39. inline matrix<T,M,N>& matrix<T,M,N>::operator+=(const T& value)
  40. {
  41. for(std::size_t i = 0; i < size(); ++i)
  42. {
  43. dptr[i] += value;
  44. }
  45. return (*this);
  46. }
  47. template<typename T, std::size_t M, std::size_t N>
  48. inline matrix<T,M,N>& matrix<T,M,N>::operator-=(const T& value)
  49. {
  50. for(std::size_t i = 0; i < size(); ++i)
  51. {
  52. dptr[i] -= value;
  53. }
  54. return (*this);
  55. }
  56. template<typename T, std::size_t M, std::size_t N>
  57. inline matrix<T,M,N>& matrix<T,M,N>::operator*=(const T& value)
  58. {
  59. for(std::size_t i = 0; i < size(); ++i)
  60. {
  61. dptr[i] *= value;
  62. }
  63. return (*this);
  64. }
  65. template<typename T, std::size_t M, std::size_t N>
  66. inline matrix<T,M,N>& matrix<T,M,N>::operator/=(const T& value)
  67. {
  68. for(std::size_t i = 0; i < size(); ++i)
  69. {
  70. dptr[i] /= value;
  71. }
  72. return (*this);
  73. }
  74. template<typename T, std::size_t M, std::size_t N>
  75. inline matrix<T,M,N>& matrix<T,M,N>::operator+=(const matrix<T,M,N>& _matrix)
  76. {
  77. for(std::size_t i = 0; i < size(); ++i)
  78. {
  79. dptr[i] += _matrix.dptr[i];
  80. }
  81. return (*this);
  82. }
  83. template<typename T, std::size_t M, std::size_t N>
  84. inline matrix<T,M,N>& matrix<T,M,N>::operator-=(const matrix<T,M,N>& _matrix)
  85. {
  86. for(std::size_t i = 0; i < size(); ++i)
  87. {
  88. dptr[i] -= _matrix.dptr[i];
  89. }
  90. return (*this);
  91. }
  92. template<typename T, std::size_t M, std::size_t N>
  93. inline void matrix<T,M,N>::zero()
  94. {
  95. for(std::size_t i = 0; i < size(); ++i)
  96. {
  97. dptr[i] = T(0.0);
  98. }
  99. }
  100. template<typename T, std::size_t M, std::size_t N>
  101. inline void matrix<T,M,N>::identity()
  102. {
  103. for(std::size_t x = 0; x < M; ++x)
  104. {
  105. for(std::size_t y = 0; y < N; ++y)
  106. {
  107. data[x][y] = ((x == y) ? T(1.0) : T(0.0));
  108. }
  109. }
  110. }
  111. template<typename T, std::size_t M, std::size_t N>
  112. inline void matrix<T,M,N>::swap(const unsigned int& x1,const unsigned int& y1,
  113. const unsigned int& x2,const unsigned int& y2)
  114. {
  115. T temp = data[x1][y1];
  116. data[x1][y1] = data[x2][y2];
  117. data[x2][y2] = temp;
  118. }
  119. template<typename T>
  120. inline void transpose(matrix<T,1,1>& matrix)
  121. {
  122. }
  123. template<typename T>
  124. inline void transpose(matrix<T,2,2>& matrix)
  125. {
  126. matrix.swap(0,1,1,0);
  127. }
  128. template<typename T> inline void transpose(matrix<T,3,3>& matrix)
  129. {
  130. matrix.swap(0,1,1,0);
  131. matrix.swap(0,2,2,0);
  132. matrix.swap(1,2,2,1);
  133. }
  134. template<typename T> inline void transpose(matrix<T,4,4>& matrix)
  135. {
  136. matrix.swap(0,1,1,0);
  137. matrix.swap(0,2,2,0);
  138. matrix.swap(0,3,3,0);
  139. matrix.swap(1,2,2,1);
  140. matrix.swap(1,3,3,1);
  141. matrix.swap(2,3,3,2);
  142. }
  143. template<typename T>
  144. inline T det(const matrix<T,1,1>& matrix)
  145. {
  146. return matrix(0,0);
  147. }
  148. template<typename T>
  149. inline T det(const matrix<T,2,2>& m)
  150. {
  151. return m[0] * m[3] - m[1] * m[2];
  152. }
  153. template<typename T>
  154. inline T det(const matrix<T,3,3>& m)
  155. {
  156. return (m(0,0) * (m(1,1) * m(2,2) - m(1,2) * m(2,1)) -
  157. m(1,0) * (m(0,1) * m(2,2) - m(0,2) * m(2,1)) +
  158. m(2,0) * (m(0,1) * m(1,2) - m(0,2) * m(1,1)));
  159. }
  160. template<typename T>
  161. inline T det(const matrix<T,4,4>& m)
  162. {
  163. T A0 = m[ 0] * m[ 5] - m[ 1] * m[ 4];
  164. T A1 = m[ 0] * m[ 6] - m[ 2] * m[ 4];
  165. T A2 = m[ 0] * m[ 7] - m[ 3] * m[ 4];
  166. T A3 = m[ 1] * m[ 6] - m[ 2] * m[ 5];
  167. T A4 = m[ 1] * m[ 7] - m[ 3] * m[ 5];
  168. T A5 = m[ 2] * m[ 7] - m[ 3] * m[ 6];
  169. T B0 = m[ 8] * m[13] - m[ 9] * m[12];
  170. T B1 = m[ 8] * m[14] - m[10] * m[12];
  171. T B2 = m[ 8] * m[15] - m[11] * m[12];
  172. T B3 = m[ 9] * m[14] - m[10] * m[13];
  173. T B4 = m[ 9] * m[15] - m[11] * m[13];
  174. T B5 = m[10] * m[15] - m[11] * m[14];
  175. return A0 * B5 - A1 * B4 + A2 * B3 + A3 * B2 - A4 * B1 + A5 * B0;
  176. }
  177. template<typename T>
  178. inline matrix<T,2,2> inverse(const matrix<T,2,2>& m)
  179. {
  180. T d = det(m);
  181. if (d != T(0.0))
  182. {
  183. matrix<T,2,2> m_;
  184. d = T(1.0) / d;
  185. m_(0,0) = m(1,1) * d;
  186. m_(1,1) = m(0,0) * d;
  187. m_(1,0) *= T(-1.0) * m(1,0) * d;
  188. m_(0,1) *= T(-1.0) * m(0,1) * d;
  189. return m_;
  190. }
  191. else
  192. return matrix<T,2,2>();
  193. }
  194. template<typename T>
  195. inline matrix<T,3,3> inverse(const matrix<T,3,3>& m)
  196. {
  197. T d = det(m);
  198. if (d != T(0.0))
  199. {
  200. matrix<T,3,3> m_;
  201. d = T(1.0) / d;
  202. m_(0,0) = (m(1,1) * m(2,2) - m(1,2) * m(2,1))* d;
  203. m_(0,1) = (m(0,2) * m(2,1) - m(0,1) * m(2,2))* d;
  204. m_(0,2) = (m(0,1) * m(1,2) - m(0,2) * m(1,1))* d;
  205. m_(1,0) = (m(1,2) * m(2,0) - m(1,0) * m(2,2))* d;
  206. m_(1,1) = (m(0,0) * m(2,2) - m(0,2) * m(2,0))* d;
  207. m_(1,2) = (m(0,2) * m(1,0) - m(0,0) * m(1,2))* d;
  208. m_(2,0) = (m(1,0) * m(2,1) - m(1,1) * m(2,0))* d;
  209. m_(2,1) = (m(0,1) * m(2,0) - m(0,0) * m(2,1))* d;
  210. m_(2,2) = (m(0,0) * m(1,1) - m(0,1) * m(1,0))* d;
  211. return m_;
  212. }
  213. else
  214. return matrix<T,3,3>();
  215. }
  216. template<typename T>
  217. inline matrix<T,4,4> inverse(const matrix<T,4,4>& m)
  218. {
  219. T A0 = m[ 0] * m[ 5] - m[ 1] * m[ 4];
  220. T A1 = m[ 0] * m[ 6] - m[ 2] * m[ 4];
  221. T A2 = m[ 0] * m[ 7] - m[ 3] * m[ 4];
  222. T A3 = m[ 1] * m[ 6] - m[ 2] * m[ 5];
  223. T A4 = m[ 1] * m[ 7] - m[ 3] * m[ 5];
  224. T A5 = m[ 2] * m[ 7] - m[ 3] * m[ 6];
  225. T B0 = m[ 8] * m[13] - m[ 9] * m[12];
  226. T B1 = m[ 8] * m[14] - m[10] * m[12];
  227. T B2 = m[ 8] * m[15] - m[11] * m[12];
  228. T B3 = m[ 9] * m[14] - m[10] * m[13];
  229. T B4 = m[ 9] * m[15] - m[11] * m[13];
  230. T B5 = m[10] * m[15] - m[11] * m[14];
  231. T d = A0 * B5 - A1 * B4 + A2 * B3 + A3 * B2 - A4 * B1 + A5 * B0;
  232. if (not_equal(d, T(0.0)))
  233. {
  234. matrix<T,4,4> m_;
  235. d = T(1.0) / d;
  236. m_[ 0] = (+m[ 5] * B5 - m[ 6] * B4 + m[ 7] * B3) * d;
  237. m_[ 1] = (-m[ 1] * B5 + m[ 2] * B4 - m[ 3] * B3) * d;
  238. m_[ 2] = (+m[13] * A5 - m[14] * A4 + m[15] * A3) * d;
  239. m_[ 3] = (-m[ 9] * A5 + m[10] * A4 - m[11] * A3) * d;
  240. m_[ 4] = (-m[ 4] * B5 + m[ 6] * B2 - m[ 7] * B1) * d;
  241. m_[ 5] = (+m[ 0] * B5 - m[ 2] * B2 + m[ 3] * B1) * d;
  242. m_[ 6] = (-m[12] * A5 + m[14] * A2 - m[15] * A1) * d;
  243. m_[ 7] = (+m[ 8] * A5 - m[10] * A2 + m[11] * A1) * d;
  244. m_[ 8] = (+m[ 4] * B4 - m[ 5] * B2 + m[ 7] * B0) * d;
  245. m_[ 9] = (-m[ 0] * B4 + m[ 1] * B2 - m[ 3] * B0) * d;
  246. m_[10] = (+m[12] * A4 - m[13] * A2 + m[15] * A0) * d;
  247. m_[11] = (-m[ 8] * A4 + m[ 9] * A2 - m[11] * A0) * d;
  248. m_[12] = (-m[ 4] * B3 + m[ 5] * B1 - m[ 6] * B0) * d;
  249. m_[13] = (+m[ 0] * B3 - m[ 1] * B1 + m[ 2] * B0) * d;
  250. m_[14] = (-m[12] * A3 + m[13] * A1 - m[14] * A0) * d;
  251. m_[15] = (+m[ 8] * A3 - m[ 9] * A1 + m[10] * A0) * d;
  252. return m_;
  253. }
  254. else
  255. return matrix<T,4,4>();
  256. }
  257. template<typename T, std::size_t N>
  258. inline void inverse(matrix<T,N,N>& out_matrix, const matrix<T,N,N>& in_matrix)
  259. {
  260. out_matrix = inverse(in_matrix);
  261. }
  262. template<typename T>
  263. inline void eigenvalues(const matrix<T,2,2>& matrix, T& eigenvalue1, T& eigenvalue2)
  264. {
  265. T delta = sqrt<T>(sqr<T>(matrix(0,0) - matrix(1,1)) + T(4.0) * matrix(1,0) * matrix(0,1));
  266. eigenvalue1 = T(0.5) * (matrix(0,0) + matrix(1,1) + delta);
  267. eigenvalue2 = T(0.5) * (matrix(0,0) + matrix(1,1) - delta);
  268. }
  269. template<typename T>
  270. inline void eigenvector(const matrix<T,2,2>& matrix,
  271. vector2d<T>& eigenvector1,
  272. vector2d<T>& eigenvector2)
  273. {
  274. T eigenvalue1;
  275. T eigenvalue2;
  276. eigenvalues(matrix,eigenvalue1,eigenvalue2);
  277. eigenvector1 = normalize(make_vector(T(-1.0) * matrix(1,0), matrix(0,0) - eigenvalue1));
  278. eigenvector2 = normalize(make_vector(T(-1.0) * matrix(1,0), matrix(0,0) - eigenvalue2));
  279. }
  280. } // namespace wykobi