Axisang.h 3.6 KB

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