Axisang.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/math/CommonIncludes.h>
  7. namespace anki
  8. {
  9. /// @addtogroup math
  10. /// @{
  11. /// Axis angles. Used in rotations.
  12. template<typename T>
  13. class TAxisang
  14. {
  15. public:
  16. /// @name Constructors
  17. /// @{
  18. TAxisang()
  19. : m_ang(0.0)
  20. , m_axis(0.0)
  21. {
  22. }
  23. TAxisang(const TAxisang& b)
  24. : m_ang(b.m_ang)
  25. , m_axis(b.m_axis)
  26. {
  27. }
  28. TAxisang(const T rad, const TVec3<T>& axis)
  29. : m_ang(rad)
  30. , m_axis(axis)
  31. {
  32. }
  33. explicit TAxisang(const TQuat<T>& q)
  34. {
  35. m_ang = 2.0 * acos<T>(q.w());
  36. T length = sqrt<T>(1.0 - q.w() * q.w());
  37. if(!isZero<T>(length))
  38. {
  39. length = 1.0 / length;
  40. m_axis = TVec3<T>(q.x() * length, q.y() * length, q.z() * length);
  41. }
  42. else
  43. {
  44. m_axis = TVec3<T>(0.0);
  45. }
  46. }
  47. explicit TAxisang(const TMat3<T>& m3)
  48. {
  49. if(isZero<T>(m3(0, 1) - m3(1, 0)) && isZero<T>(m3(0, 2) - m3(2, 0))
  50. && isZero<T>(m3(1, 2) - m3(2, 1)))
  51. {
  52. if((fabs<T>(m3(0, 1) + m3(1, 0)) < 0.1)
  53. && (fabs<T>(m3(0, 2) + m3(2, 0)) < 0.1)
  54. && (fabs<T>(m3(1, 2) + m3(2, 1)) < 0.1)
  55. && (fabs<T>(m3(0, 0) + m3(1, 1) + m3(2, 2)) - 3) < 0.1)
  56. {
  57. m_axis = TVec3<T>(1.0, 0.0, 0.0);
  58. m_ang = 0.0;
  59. return;
  60. }
  61. m_ang = getPi<T>();
  62. m_axis.x() = (m3(0, 0) + 1.0) / 2.0;
  63. if(m_axis.x() > 0.0)
  64. {
  65. m_axis.x() = sqrt(m_axis.x());
  66. }
  67. else
  68. {
  69. m_axis.x() = 0.0;
  70. }
  71. m_axis.y() = (m3(1, 1) + 1.0) / 2.0;
  72. if(m_axis.y() > 0.0)
  73. {
  74. m_axis.y() = sqrt(m_axis.y());
  75. }
  76. else
  77. {
  78. m_axis.y() = 0.0;
  79. }
  80. m_axis.z() = (m3(2, 2) + 1.0) / 2.0;
  81. if(m_axis.z() > 0.0)
  82. {
  83. m_axis.z() = sqrt(m_axis.z());
  84. }
  85. else
  86. {
  87. m_axis.z() = 0.0;
  88. }
  89. Bool xZero = isZero<T>(m_axis.x());
  90. Bool yZero = isZero<T>(m_axis.y());
  91. Bool zZero = isZero<T>(m_axis.z());
  92. Bool xyPositive = (m3(0, 1) > 0);
  93. Bool xzPositive = (m3(0, 2) > 0);
  94. Bool yzPositive = (m3(1, 2) > 0);
  95. if(xZero && !yZero && !zZero)
  96. {
  97. if(!yzPositive)
  98. {
  99. m_axis.y() = -m_axis.y();
  100. }
  101. }
  102. else if(yZero && !zZero)
  103. {
  104. if(!xzPositive)
  105. {
  106. m_axis.z() = -m_axis.z();
  107. }
  108. }
  109. else if(zZero)
  110. {
  111. if(!xyPositive)
  112. {
  113. m_axis.x() = -m_axis.x();
  114. }
  115. }
  116. return;
  117. }
  118. T s = sqrt((m3(2, 1) - m3(1, 2)) * (m3(2, 1) - m3(1, 2))
  119. + (m3(0, 2) - m3(2, 0)) * (m3(0, 2) - m3(2, 0))
  120. + (m3(1, 0) - m3(0, 1)) * (m3(1, 0) - m3(0, 1)));
  121. if(fabs(s) < 0.001)
  122. {
  123. s = 1.0;
  124. }
  125. m_ang = acos<T>((m3(0, 0) + m3(1, 1) + m3(2, 2) - 1.0) / 2.0);
  126. m_axis.x() = (m3(2, 1) - m3(1, 2)) / s;
  127. m_axis.y() = (m3(0, 2) - m3(2, 0)) / s;
  128. m_axis.z() = (m3(1, 0) - m3(0, 1)) / s;
  129. }
  130. /// @}
  131. /// @name Accessors
  132. /// @{
  133. T getAngle() const
  134. {
  135. return m_ang;
  136. }
  137. T& getAngle()
  138. {
  139. return m_ang;
  140. }
  141. void setAngle(const T a)
  142. {
  143. m_ang = a;
  144. }
  145. const TVec3<T>& getAxis() const
  146. {
  147. return m_axis;
  148. }
  149. TVec3<T>& getAxis()
  150. {
  151. return m_axis;
  152. }
  153. void setAxis(const TVec3<T>& a)
  154. {
  155. m_axis = a;
  156. }
  157. /// @}
  158. /// @name Operators with same type
  159. /// @{
  160. TAxisang& operator=(const TAxisang& b)
  161. {
  162. m_ang = b.m_ang;
  163. m_axis = b.m_axis;
  164. return *this;
  165. }
  166. /// @}
  167. /// @name Other
  168. /// @{
  169. template<typename TAlloc>
  170. String toString(TAlloc alloc) const
  171. {
  172. String s;
  173. Error err = s.sprintf("axis: %f %f %f, angle: %f",
  174. m_axis[0],
  175. m_axis[1],
  176. m_axis[2],
  177. m_ang);
  178. (void)err;
  179. return s;
  180. }
  181. /// @}
  182. private:
  183. /// @name Data
  184. /// @{
  185. T m_ang;
  186. TVec3<T> m_axis;
  187. /// @}
  188. };
  189. /// F32 Axisang
  190. typedef TAxisang<F32> Axisang;
  191. /// @}
  192. } // end namespace anki