Math.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * Copyright 2010 SRI International
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef OPEN_KARTO_MATH_H
  18. #define OPEN_KARTO_MATH_H
  19. #include <assert.h>
  20. #include <math.h>
  21. #include <limits>
  22. #include <open_karto/Types.h>
  23. namespace karto
  24. {
  25. /**
  26. * Platform independent pi definitions
  27. */
  28. const kt_double KT_PI = 3.14159265358979323846; // The value of PI
  29. const kt_double KT_2PI = 6.28318530717958647692; // 2 * PI
  30. const kt_double KT_PI_2 = 1.57079632679489661923; // PI / 2
  31. const kt_double KT_PI_180 = 0.01745329251994329577; // PI / 180
  32. const kt_double KT_180_PI = 57.29577951308232087685; // 180 / PI
  33. /**
  34. * Lets define a small number!
  35. */
  36. const kt_double KT_TOLERANCE = 1e-06;
  37. /**
  38. * Lets define max value of kt_int32s (int32_t) to use it to mark invalid scans
  39. */
  40. const kt_int32s INVALID_SCAN = std::numeric_limits<kt_int32s>::max();
  41. namespace math
  42. {
  43. /**
  44. * Converts degrees into radians
  45. * @param degrees
  46. * @return radian equivalent of degrees
  47. */
  48. inline kt_double DegreesToRadians(kt_double degrees)
  49. {
  50. return degrees * KT_PI_180;
  51. }
  52. /**
  53. * Converts radians into degrees
  54. * @param radians
  55. * @return degree equivalent of radians
  56. */
  57. inline kt_double RadiansToDegrees(kt_double radians)
  58. {
  59. return radians * KT_180_PI;
  60. }
  61. /**
  62. * Square function
  63. * @param value
  64. * @return square of value
  65. */
  66. template<typename T>
  67. inline T Square(T value)
  68. {
  69. return (value * value);
  70. }
  71. /**
  72. * Round function
  73. * @param value
  74. * @return rounds value to the nearest whole number (as double)
  75. */
  76. inline kt_double Round(kt_double value)
  77. {
  78. return value >= 0.0 ? floor(value + 0.5) : ceil(value - 0.5);
  79. }
  80. /**
  81. * Binary minimum function
  82. * @param value1
  83. * @param value2
  84. * @return the lesser of value1 and value2
  85. */
  86. template<typename T>
  87. inline const T& Minimum(const T& value1, const T& value2)
  88. {
  89. return value1 < value2 ? value1 : value2;
  90. }
  91. /**
  92. * Binary maximum function
  93. * @param value1
  94. * @param value2
  95. * @return the greater of value1 and value2
  96. */
  97. template<typename T>
  98. inline const T& Maximum(const T& value1, const T& value2)
  99. {
  100. return value1 > value2 ? value1 : value2;
  101. }
  102. /**
  103. * Clips a number to the specified minimum and maximum values.
  104. * @param n number to be clipped
  105. * @param minValue minimum value
  106. * @param maxValue maximum value
  107. * @return the clipped value
  108. */
  109. template<typename T>
  110. inline const T& Clip(const T& n, const T& minValue, const T& maxValue)
  111. {
  112. return Minimum(Maximum(n, minValue), maxValue);
  113. }
  114. /**
  115. * Checks whether two numbers are equal within a certain tolerance.
  116. * @param a
  117. * @param b
  118. * @return true if a and b differ by at most a certain tolerance.
  119. */
  120. inline kt_bool DoubleEqual(kt_double a, kt_double b)
  121. {
  122. double delta = a - b;
  123. return delta < 0.0 ? delta >= -KT_TOLERANCE : delta <= KT_TOLERANCE;
  124. }
  125. /**
  126. * Checks whether value is in the range [0;maximum)
  127. * @param value
  128. * @param maximum
  129. */
  130. template<typename T>
  131. inline kt_bool IsUpTo(const T& value, const T& maximum)
  132. {
  133. return (value >= 0 && value < maximum);
  134. }
  135. /**
  136. * Checks whether value is in the range [0;maximum)
  137. * Specialized version for unsigned int (kt_int32u)
  138. * @param value
  139. * @param maximum
  140. */
  141. template<>
  142. inline kt_bool IsUpTo<kt_int32u>(const kt_int32u& value, const kt_int32u& maximum)
  143. {
  144. return (value < maximum);
  145. }
  146. /**
  147. * Checks whether value is in the range [a;b]
  148. * @param value
  149. * @param a
  150. * @param b
  151. */
  152. template<typename T>
  153. inline kt_bool InRange(const T& value, const T& a, const T& b)
  154. {
  155. return (value >= a && value <= b);
  156. }
  157. /**
  158. * Normalizes angle to be in the range of [-pi, pi]
  159. * @param angle to be normalized
  160. * @return normalized angle
  161. */
  162. inline kt_double NormalizeAngle(kt_double angle)
  163. {
  164. while (angle < -KT_PI)
  165. {
  166. if (angle < -KT_2PI)
  167. {
  168. angle += (kt_int32u)(angle / -KT_2PI) * KT_2PI;
  169. }
  170. else
  171. {
  172. angle += KT_2PI;
  173. }
  174. }
  175. while (angle > KT_PI)
  176. {
  177. if (angle > KT_2PI)
  178. {
  179. angle -= (kt_int32u)(angle / KT_2PI) * KT_2PI;
  180. }
  181. else
  182. {
  183. angle -= KT_2PI;
  184. }
  185. }
  186. assert(math::InRange(angle, -KT_PI, KT_PI));
  187. return angle;
  188. }
  189. /**
  190. * Returns an equivalent angle to the first parameter such that the difference
  191. * when the second parameter is subtracted from this new value is an angle
  192. * in the normalized range of [-pi, pi], i.e. abs(minuend - subtrahend) <= pi.
  193. * @param minuend
  194. * @param subtrahend
  195. * @return normalized angle
  196. */
  197. inline kt_double NormalizeAngleDifference(kt_double minuend, kt_double subtrahend)
  198. {
  199. while (minuend - subtrahend < -KT_PI)
  200. {
  201. minuend += KT_2PI;
  202. }
  203. while (minuend - subtrahend > KT_PI)
  204. {
  205. minuend -= KT_2PI;
  206. }
  207. return minuend;
  208. }
  209. /**
  210. * Align a value to the alignValue.
  211. * The alignValue should be the power of two (2, 4, 8, 16, 32 and so on)
  212. * @param value
  213. * @param alignValue
  214. * @return aligned value
  215. */
  216. template<class T>
  217. inline T AlignValue(size_t value, size_t alignValue = 8)
  218. {
  219. return static_cast<T> ((value + (alignValue - 1)) & ~(alignValue - 1));
  220. }
  221. } // namespace math
  222. } // namespace karto
  223. #endif // OPEN_KARTO_MATH_H