Axisang.h 3.2 KB

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