gtx_euler_angle.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2013-10-25
  5. // Updated : 2014-01-11
  6. // Licence : This source is under MIT licence
  7. // File : test/gtx/euler_angle.cpp
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. // Code sample from Filippo Ramaciotti
  10. #include <glm/gtc/matrix_transform.hpp>
  11. #include <glm/gtc/epsilon.hpp>
  12. #include <glm/gtx/string_cast.hpp>
  13. #include <glm/gtx/euler_angles.hpp>
  14. #include <iostream>
  15. namespace test_eulerAngleX
  16. {
  17. int test()
  18. {
  19. int Error = 0;
  20. float const Angle(glm::pi<float>() * 0.5f);
  21. glm::vec3 const X(1.0f, 0.0f, 0.0f);
  22. glm::vec4 const Y(0.0f, 1.0f, 0.0f, 1.0f);
  23. glm::vec4 const Y1 = glm::rotate(glm::mat4(1.0f), Angle, X) * Y;
  24. glm::vec4 const Y2 = glm::eulerAngleX(Angle) * Y;
  25. glm::vec4 const Y3 = glm::eulerAngleXY(Angle, 0.0f) * Y;
  26. glm::vec4 const Y4 = glm::eulerAngleYX(0.0f, Angle) * Y;
  27. glm::vec4 const Y5 = glm::eulerAngleXZ(Angle, 0.0f) * Y;
  28. glm::vec4 const Y6 = glm::eulerAngleZX(0.0f, Angle) * Y;
  29. glm::vec4 const Y7 = glm::eulerAngleYXZ(0.0f, Angle, 0.0f) * Y;
  30. Error += glm::all(glm::epsilonEqual(Y1, Y2, 0.00001f)) ? 0 : 1;
  31. Error += glm::all(glm::epsilonEqual(Y1, Y3, 0.00001f)) ? 0 : 1;
  32. Error += glm::all(glm::epsilonEqual(Y1, Y4, 0.00001f)) ? 0 : 1;
  33. Error += glm::all(glm::epsilonEqual(Y1, Y5, 0.00001f)) ? 0 : 1;
  34. Error += glm::all(glm::epsilonEqual(Y1, Y6, 0.00001f)) ? 0 : 1;
  35. Error += glm::all(glm::epsilonEqual(Y1, Y7, 0.00001f)) ? 0 : 1;
  36. glm::vec4 const Z(0.0f, 0.0f, 1.0f, 1.0f);
  37. glm::vec4 const Z1 = glm::rotate(glm::mat4(1.0f), Angle, X) * Z;
  38. glm::vec4 const Z2 = glm::eulerAngleX(Angle) * Z;
  39. glm::vec4 const Z3 = glm::eulerAngleXY(Angle, 0.0f) * Z;
  40. glm::vec4 const Z4 = glm::eulerAngleYX(0.0f, Angle) * Z;
  41. glm::vec4 const Z5 = glm::eulerAngleXZ(Angle, 0.0f) * Z;
  42. glm::vec4 const Z6 = glm::eulerAngleZX(0.0f, Angle) * Z;
  43. glm::vec4 const Z7 = glm::eulerAngleYXZ(0.0f, Angle, 0.0f) * Z;
  44. Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1;
  45. Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1;
  46. Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1;
  47. Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1;
  48. Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1;
  49. Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1;
  50. return Error;
  51. }
  52. }//namespace test_eulerAngleX
  53. namespace test_eulerAngleY
  54. {
  55. int test()
  56. {
  57. int Error = 0;
  58. float const Angle(glm::pi<float>() * 0.5f);
  59. glm::vec3 const Y(0.0f, 1.0f, 0.0f);
  60. glm::vec4 const X(1.0f, 0.0f, 0.0f, 1.0f);
  61. glm::vec4 const X1 = glm::rotate(glm::mat4(1.0f), Angle, Y) * X;
  62. glm::vec4 const X2 = glm::eulerAngleY(Angle) * X;
  63. glm::vec4 const X3 = glm::eulerAngleYX(Angle, 0.0f) * X;
  64. glm::vec4 const X4 = glm::eulerAngleXY(0.0f, Angle) * X;
  65. glm::vec4 const X5 = glm::eulerAngleYZ(Angle, 0.0f) * X;
  66. glm::vec4 const X6 = glm::eulerAngleZY(0.0f, Angle) * X;
  67. glm::vec4 const X7 = glm::eulerAngleYXZ(Angle, 0.0f, 0.0f) * X;
  68. Error += glm::all(glm::epsilonEqual(X1, X2, 0.00001f)) ? 0 : 1;
  69. Error += glm::all(glm::epsilonEqual(X1, X3, 0.00001f)) ? 0 : 1;
  70. Error += glm::all(glm::epsilonEqual(X1, X4, 0.00001f)) ? 0 : 1;
  71. Error += glm::all(glm::epsilonEqual(X1, X5, 0.00001f)) ? 0 : 1;
  72. Error += glm::all(glm::epsilonEqual(X1, X6, 0.00001f)) ? 0 : 1;
  73. Error += glm::all(glm::epsilonEqual(X1, X7, 0.00001f)) ? 0 : 1;
  74. glm::vec4 const Z(0.0f, 0.0f, 1.0f, 1.0f);
  75. glm::vec4 const Z1 = glm::eulerAngleY(Angle) * Z;
  76. glm::vec4 const Z2 = glm::rotate(glm::mat4(1.0f), Angle, Y) * Z;
  77. glm::vec4 const Z3 = glm::eulerAngleYX(Angle, 0.0f) * Z;
  78. glm::vec4 const Z4 = glm::eulerAngleXY(0.0f, Angle) * Z;
  79. glm::vec4 const Z5 = glm::eulerAngleYZ(Angle, 0.0f) * Z;
  80. glm::vec4 const Z6 = glm::eulerAngleZY(0.0f, Angle) * Z;
  81. glm::vec4 const Z7 = glm::eulerAngleYXZ(Angle, 0.0f, 0.0f) * Z;
  82. Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1;
  83. Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1;
  84. Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1;
  85. Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1;
  86. Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1;
  87. Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1;
  88. return Error;
  89. }
  90. }//namespace test_eulerAngleY
  91. namespace test_eulerAngleZ
  92. {
  93. int test()
  94. {
  95. int Error = 0;
  96. float const Angle(glm::pi<float>() * 0.5f);
  97. glm::vec3 const Z(0.0f, 0.0f, 1.0f);
  98. glm::vec4 const X(1.0f, 0.0f, 0.0f, 1.0f);
  99. glm::vec4 const X1 = glm::rotate(glm::mat4(1.0f), Angle, Z) * X;
  100. glm::vec4 const X2 = glm::eulerAngleZ(Angle) * X;
  101. glm::vec4 const X3 = glm::eulerAngleZX(Angle, 0.0f) * X;
  102. glm::vec4 const X4 = glm::eulerAngleXZ(0.0f, Angle) * X;
  103. glm::vec4 const X5 = glm::eulerAngleZY(Angle, 0.0f) * X;
  104. glm::vec4 const X6 = glm::eulerAngleYZ(0.0f, Angle) * X;
  105. glm::vec4 const X7 = glm::eulerAngleYXZ(0.0f, 0.0f, Angle) * X;
  106. Error += glm::all(glm::epsilonEqual(X1, X2, 0.00001f)) ? 0 : 1;
  107. Error += glm::all(glm::epsilonEqual(X1, X3, 0.00001f)) ? 0 : 1;
  108. Error += glm::all(glm::epsilonEqual(X1, X4, 0.00001f)) ? 0 : 1;
  109. Error += glm::all(glm::epsilonEqual(X1, X5, 0.00001f)) ? 0 : 1;
  110. Error += glm::all(glm::epsilonEqual(X1, X6, 0.00001f)) ? 0 : 1;
  111. Error += glm::all(glm::epsilonEqual(X1, X7, 0.00001f)) ? 0 : 1;
  112. glm::vec4 const Y(1.0f, 0.0f, 0.0f, 1.0f);
  113. glm::vec4 const Z1 = glm::rotate(glm::mat4(1.0f), Angle, Z) * Y;
  114. glm::vec4 const Z2 = glm::eulerAngleZ(Angle) * Y;
  115. glm::vec4 const Z3 = glm::eulerAngleZX(Angle, 0.0f) * Y;
  116. glm::vec4 const Z4 = glm::eulerAngleXZ(0.0f, Angle) * Y;
  117. glm::vec4 const Z5 = glm::eulerAngleZY(Angle, 0.0f) * Y;
  118. glm::vec4 const Z6 = glm::eulerAngleYZ(0.0f, Angle) * Y;
  119. glm::vec4 const Z7 = glm::eulerAngleYXZ(0.0f, 0.0f, Angle) * Y;
  120. Error += glm::all(glm::epsilonEqual(Z1, Z2, 0.00001f)) ? 0 : 1;
  121. Error += glm::all(glm::epsilonEqual(Z1, Z3, 0.00001f)) ? 0 : 1;
  122. Error += glm::all(glm::epsilonEqual(Z1, Z4, 0.00001f)) ? 0 : 1;
  123. Error += glm::all(glm::epsilonEqual(Z1, Z5, 0.00001f)) ? 0 : 1;
  124. Error += glm::all(glm::epsilonEqual(Z1, Z6, 0.00001f)) ? 0 : 1;
  125. Error += glm::all(glm::epsilonEqual(Z1, Z7, 0.00001f)) ? 0 : 1;
  126. return Error;
  127. }
  128. }//namespace test_eulerAngleZ
  129. namespace test_eulerAngleXY
  130. {
  131. int test()
  132. {
  133. int Error = 0;
  134. glm::vec4 const V(1.0f);
  135. float const AngleX(glm::pi<float>() * 0.5f);
  136. float const AngleY(glm::pi<float>() * 0.25f);
  137. glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
  138. glm::vec3 const axisY(0.0f, 1.0f, 0.0f);
  139. glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleX, axisX) * glm::rotate(glm::mat4(1.0f), AngleY, axisY)) * V;
  140. glm::vec4 const V2 = glm::eulerAngleXY(AngleX, AngleY) * V;
  141. glm::vec4 const V3 = glm::eulerAngleX(AngleX) * glm::eulerAngleY(AngleY) * V;
  142. Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
  143. Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
  144. return Error;
  145. }
  146. }//namespace test_eulerAngleXY
  147. namespace test_eulerAngleYX
  148. {
  149. int test()
  150. {
  151. int Error = 0;
  152. glm::vec4 const V(1.0f);
  153. float const AngleX(glm::pi<float>() * 0.5f);
  154. float const AngleY(glm::pi<float>() * 0.25f);
  155. glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
  156. glm::vec3 const axisY(0.0f, 1.0f, 0.0f);
  157. glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleY, axisY) * glm::rotate(glm::mat4(1.0f), AngleX, axisX)) * V;
  158. glm::vec4 const V2 = glm::eulerAngleYX(AngleY, AngleX) * V;
  159. glm::vec4 const V3 = glm::eulerAngleY(AngleY) * glm::eulerAngleX(AngleX) * V;
  160. Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
  161. Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
  162. return Error;
  163. }
  164. }//namespace test_eulerAngleYX
  165. namespace test_eulerAngleXZ
  166. {
  167. int test()
  168. {
  169. int Error = 0;
  170. glm::vec4 const V(1.0f);
  171. float const AngleX(glm::pi<float>() * 0.5f);
  172. float const AngleZ(glm::pi<float>() * 0.25f);
  173. glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
  174. glm::vec3 const axisZ(0.0f, 0.0f, 1.0f);
  175. glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleX, axisX) * glm::rotate(glm::mat4(1.0f), AngleZ, axisZ)) * V;
  176. glm::vec4 const V2 = glm::eulerAngleXZ(AngleX, AngleZ) * V;
  177. glm::vec4 const V3 = glm::eulerAngleX(AngleX) * glm::eulerAngleZ(AngleZ) * V;
  178. Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
  179. Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
  180. return Error;
  181. }
  182. }//namespace test_eulerAngleXZ
  183. namespace test_eulerAngleZX
  184. {
  185. int test()
  186. {
  187. int Error = 0;
  188. glm::vec4 const V(1.0f);
  189. float const AngleX(glm::pi<float>() * 0.5f);
  190. float const AngleZ(glm::pi<float>() * 0.25f);
  191. glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
  192. glm::vec3 const axisZ(0.0f, 0.0f, 1.0f);
  193. glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleZ, axisZ) * glm::rotate(glm::mat4(1.0f), AngleX, axisX)) * V;
  194. glm::vec4 const V2 = glm::eulerAngleZX(AngleZ, AngleX) * V;
  195. glm::vec4 const V3 = glm::eulerAngleZ(AngleZ) * glm::eulerAngleX(AngleX) * V;
  196. Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
  197. Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
  198. return Error;
  199. }
  200. }//namespace test_eulerAngleZX
  201. namespace test_eulerAngleYZ
  202. {
  203. int test()
  204. {
  205. int Error = 0;
  206. glm::vec4 const V(1.0f);
  207. float const AngleY(glm::pi<float>() * 0.5f);
  208. float const AngleZ(glm::pi<float>() * 0.25f);
  209. glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
  210. glm::vec3 const axisY(0.0f, 1.0f, 0.0f);
  211. glm::vec3 const axisZ(0.0f, 0.0f, 1.0f);
  212. glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleY, axisY) * glm::rotate(glm::mat4(1.0f), AngleZ, axisZ)) * V;
  213. glm::vec4 const V2 = glm::eulerAngleYZ(AngleY, AngleZ) * V;
  214. glm::vec4 const V3 = glm::eulerAngleY(AngleY) * glm::eulerAngleZ(AngleZ) * V;
  215. Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
  216. Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
  217. return Error;
  218. }
  219. }//namespace test_eulerAngleYZ
  220. namespace test_eulerAngleZY
  221. {
  222. int test()
  223. {
  224. int Error = 0;
  225. glm::vec4 const V(1.0f);
  226. float const AngleY(glm::pi<float>() * 0.5f);
  227. float const AngleZ(glm::pi<float>() * 0.25f);
  228. glm::vec3 const axisX(1.0f, 0.0f, 0.0f);
  229. glm::vec3 const axisY(0.0f, 1.0f, 0.0f);
  230. glm::vec3 const axisZ(0.0f, 0.0f, 1.0f);
  231. glm::vec4 const V1 = (glm::rotate(glm::mat4(1.0f), AngleZ, axisZ) * glm::rotate(glm::mat4(1.0f), AngleY, axisY)) * V;
  232. glm::vec4 const V2 = glm::eulerAngleZY(AngleZ, AngleY) * V;
  233. glm::vec4 const V3 = glm::eulerAngleZ(AngleZ) * glm::eulerAngleY(AngleY) * V;
  234. Error += glm::all(glm::epsilonEqual(V1, V2, 0.00001f)) ? 0 : 1;
  235. Error += glm::all(glm::epsilonEqual(V1, V3, 0.00001f)) ? 0 : 1;
  236. return Error;
  237. }
  238. }//namespace test_eulerAngleZY
  239. namespace test_eulerAngleYXZ
  240. {
  241. int test()
  242. {
  243. glm::f32 first = 1.046f;
  244. glm::f32 second = 0.52f;
  245. glm::f32 third = -0.785f;
  246. glm::fmat4 rotationEuler = glm::eulerAngleYXZ(first, second, third);
  247. glm::fmat4 rotationInvertedY = glm::eulerAngleY(-1.f*first) * glm::eulerAngleX(second) * glm::eulerAngleZ(third);
  248. glm::fmat4 rotationDumb = glm::fmat4();
  249. rotationDumb = glm::rotate(rotationDumb, first, glm::fvec3(0,1,0));
  250. rotationDumb = glm::rotate(rotationDumb, second, glm::fvec3(1,0,0));
  251. rotationDumb = glm::rotate(rotationDumb, third, glm::fvec3(0,0,1));
  252. std::cout << glm::to_string(glm::fmat3(rotationEuler)) << std::endl;
  253. std::cout << glm::to_string(glm::fmat3(rotationDumb)) << std::endl;
  254. std::cout << glm::to_string(glm::fmat3(rotationInvertedY )) << std::endl;
  255. std::cout <<"\nRESIDUAL\n";
  256. std::cout << glm::to_string(glm::fmat3(rotationEuler-(rotationDumb))) << std::endl;
  257. std::cout << glm::to_string(glm::fmat3(rotationEuler-(rotationInvertedY ))) << std::endl;
  258. return 0;
  259. }
  260. }//namespace eulerAngleYXZ
  261. int main()
  262. {
  263. int Error = 0;
  264. Error += test_eulerAngleX::test();
  265. Error += test_eulerAngleY::test();
  266. Error += test_eulerAngleZ::test();
  267. Error += test_eulerAngleXY::test();
  268. Error += test_eulerAngleYX::test();
  269. Error += test_eulerAngleXZ::test();
  270. Error += test_eulerAngleZX::test();
  271. Error += test_eulerAngleYZ::test();
  272. Error += test_eulerAngleZY::test();
  273. Error += test_eulerAngleYXZ::test();
  274. return Error;
  275. }