helpler_funtions.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. #pragma once
  2. #include <float.h>
  3. #include <math.h>
  4. #include <stdbool.h>
  5. #include <stdint.h>
  6. /* PI 宏定义 */
  7. #ifdef M_PI
  8. #undef M_PI
  9. #endif
  10. #define M_PI 3.14159265358979323846
  11. /* 重力加速度宏定义 */
  12. #ifdef GRAVITY_MSS
  13. #undef GRAVITY_MSS
  14. #endif
  15. #define GRAVITY_MSS 9.80665F
  16. #ifdef __cplusplus
  17. extern "C" {
  18. #endif
  19. /**
  20. * @brief 取两个数中较小的那个
  21. *
  22. */
  23. #define min(x, y) \
  24. ({ \
  25. typeof(x) _min1 = x; \
  26. typeof(y) _min2 = y; \
  27. (void)(&_min1 == &_min2); \
  28. _min1 < _min2 ? _min1 : _min2; \
  29. })
  30. /**
  31. * @brief 取两个数中较大的那个
  32. *
  33. */
  34. #define max(x, y) \
  35. ({ \
  36. typeof(x) _max1 = x; \
  37. typeof(y) _max2 = y; \
  38. (void)(&_max1 == &_max2); \
  39. _max1 > _max2 ? _max1 : _max2; \
  40. })
  41. #if defined DEG_TO_RAD
  42. #undef DEG_TO_RAD
  43. #endif
  44. #define DEG_TO_RAD 0.017453292519943295769236907684886 // 度换算弧度
  45. #if defined RAD_TO_DEG
  46. #undef RAD_TO_DEG
  47. #endif
  48. #define RAD_TO_DEG 57.295779513082320876798154814105 // 弧度换算度
  49. /* 弧度转角度 */
  50. #define rad_to_deg(x) ((x) * 180.0 / M_PI)
  51. /* 角度转弧度 */
  52. #define deg_to_rad(x) ((x) * M_PI / 180.0)
  53. /**
  54. * @brief 检查浮点数是否为 0
  55. *
  56. * @param fVal1 输入浮点数
  57. * @return true 浮点数为 0
  58. * @return false 浮点数不为 0
  59. */
  60. static inline bool is_zerof(const float fVal1) {
  61. return fabsf(fVal1) < FLT_EPSILON ? true : false;
  62. }
  63. /**
  64. * @brief 检查双精度浮点数是否为 0
  65. *
  66. * @param dVal1 输入双精度浮点数
  67. * @return true 浮点数为 0
  68. * @return false 浮点数不为 0
  69. */
  70. static inline bool is_zerod(const double dVal1) {
  71. return fabs(dVal1) < DBL_EPSILON ? true : false;
  72. }
  73. /**
  74. * @brief 检查两个浮点数是否相等
  75. *
  76. * @param fVal1 输入浮点数1
  77. * @param fVal2 输入浮点数2
  78. * @return true 两数相等
  79. * @return false 两数不相等
  80. */
  81. static inline bool is_equalf(const float fVal1, const float fVal2) {
  82. return fabsf(fVal1 - fVal2) < FLT_EPSILON ? true : false;
  83. }
  84. /**
  85. * @brief 检查两个双精度浮点数是否相等
  86. *
  87. * @param dVal1 输入浮点数1
  88. * @param dVal2 输入浮点数2
  89. * @return true 两数相等
  90. * @return false 两数不相等
  91. */
  92. static inline bool is_equald(const double dVal1, const double dVal2) {
  93. return fabs(dVal1 - dVal2) < DBL_EPSILON ? true : false;
  94. }
  95. /**
  96. * @brief 取浮点数的符号
  97. *
  98. * @param val 浮点数
  99. * @return int 符号 -1 或 +1
  100. */
  101. static inline int sign(float val) {
  102. return (FLT_EPSILON < val) - (val < FLT_EPSILON);
  103. }
  104. /**
  105. * @brief 将浮点 wrap 数限制在某个范围内, 常用于如角度限制在 0~360 度等
  106. *
  107. * @param x 双精度浮点数
  108. * @param low 范围下限
  109. * @param high 范围上限
  110. * @return double wrap 限制输出结果
  111. */
  112. static inline double wrap_double(double x, double low, double high) {
  113. if (low <= x && x < high) {
  114. return x;
  115. }
  116. const double range = high - low;
  117. const double inv_range = 1.0 / range;
  118. const double num_wraps = floor((x - low) * inv_range);
  119. return x - range * num_wraps;
  120. }
  121. /**
  122. * @brief 将浮点 wrap 数限制在某个范围内, 常用于如角度限制在 0~360 度等
  123. *
  124. * @param x 单精度浮点数
  125. * @param low 范围下限
  126. * @param high 范围上限
  127. * @return float wrap 限制输出结果
  128. */
  129. static inline float wrap_float(float x, float low, float high) {
  130. if (low <= x && x < high) {
  131. return x;
  132. }
  133. const float range = high - low;
  134. const float inv_range = 1.0f / range;
  135. const float num_wraps = floorf((x - low) * inv_range);
  136. return x - range * num_wraps;
  137. }
  138. static inline int wrap_int(int x, int low, int high) {
  139. if (low <= x && x < high) {
  140. return x;
  141. }
  142. const int range_size = high - low + 1;
  143. int wrapped_value = (x - low) % range_size;
  144. if (wrapped_value < 0) {
  145. wrapped_value += range_size;
  146. }
  147. return wrapped_value + range_size;
  148. }
  149. /**
  150. * @brief 将浮点 wrap 数限制在 -PI ~ PI 范围内
  151. *
  152. * @param x 单精度浮点数
  153. * @return float wrap 限制输出结果
  154. */
  155. static inline float wrap_f_pi(float x) { return wrap_float(x, -M_PI, M_PI); }
  156. /**
  157. * @brief 将浮点 wrap 数限制在 -PI ~ PI 范围内
  158. *
  159. * @param x 双精度浮点数
  160. * @return double wrap 限制输出结果
  161. */
  162. static inline double wrap_d_pi(double x) { return wrap_double(x, -M_PI, M_PI); }
  163. /**
  164. * @brief 将浮点 wrap 数限制在 -180 ~ 180 范围内
  165. *
  166. * @param x 单精度浮点数
  167. * @return float wrap 限制输出结果
  168. */
  169. static inline float wrap_f_180(float x) {
  170. return wrap_float(x, -180.0f, 180.0f);
  171. }
  172. /**
  173. * @brief 将浮点 wrap 数限制在 -180 ~ 180 范围内
  174. *
  175. * @param x 双精度浮点数
  176. * @return double wrap 限制输出结果
  177. */
  178. static inline double wrap_d_180(double x) {
  179. return wrap_double(x, -180.0, 180.0);
  180. }
  181. /**
  182. * @brief 将浮点数限制在给定范围内
  183. *
  184. * @param amt 输入单精度浮点数
  185. * @param low 范围下限
  186. * @param high 范围上限
  187. * @return float 限幅输出结果
  188. */
  189. static float constrain_float(float amt, float low, float high) {
  190. if (isnan(amt)) {
  191. return (low + high) * 0.5f;
  192. }
  193. return ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)));
  194. }
  195. /**
  196. * @brief 将浮点数限制在给定范围内
  197. *
  198. * @param amt 输入双精度浮点数
  199. * @param low 范围下限
  200. * @param high 范围上限
  201. * @return double 限幅输出结果
  202. */
  203. static double constrain_double(double amt, double low, double high) {
  204. if (isnan(amt)) {
  205. return (low + high) * 0.5;
  206. }
  207. return ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)));
  208. }
  209. /**
  210. * @brief 将整数限制在给定范围内
  211. *
  212. * @param amt 输入无符号整数
  213. * @param low 范围下限
  214. * @param high 范围上限
  215. * @return uint16_t 限幅输出结果
  216. */
  217. static uint16_t constrain_uint16(uint16_t amt, uint16_t low, uint16_t high) {
  218. return ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)));
  219. }
  220. /**
  221. * @brief 将整数限制在给定范围内
  222. *
  223. * @param amt 输入无符号整数
  224. * @param low 范围下限
  225. * @param high 范围上限
  226. * @return uint32_t 限幅输出结果
  227. */
  228. static uint32_t constrain_uint32(uint32_t amt, uint32_t low, uint32_t high) {
  229. return ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)));
  230. }
  231. /**
  232. * @brief 将整数限制在给定范围内
  233. *
  234. * @param amt 输入无符号整数
  235. * @param low 范围下限
  236. * @param high 范围上限
  237. * @return uint32_t 限幅输出结果
  238. */
  239. static int32_t constrain_int32(int32_t amt, int32_t low, int32_t high) {
  240. return ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)));
  241. }
  242. /**
  243. * @brief 计算两个数的平方和开根号
  244. *
  245. * @param x
  246. * @param y
  247. * @return float 输出结果
  248. */
  249. static inline float get_norm2(float x, float y) { return sqrtf(x * x + y * y); }
  250. /**
  251. * @brief 计算三个数的平方和开根号
  252. *
  253. * @param x
  254. * @param y
  255. * @param z
  256. * @return float 输出结果
  257. */
  258. static inline float get_norm3(float x, float y, float z) {
  259. return sqrtf(x * x + y * y + z * z);
  260. }
  261. /** @brief 插入排序算法
  262. * @param int arr[]被排数列,int n 排序窗宽
  263. * @retval none
  264. */
  265. static inline void insert_sort(int arr[], int n) {
  266. int temp;
  267. int i, j;
  268. for (i = 1; i < n; ++i) {
  269. temp = arr[i];
  270. for (j = i; j > 0 && temp < arr[j - 1]; --j) {
  271. arr[j] = arr[j - 1];
  272. }
  273. arr[j] = temp;
  274. }
  275. }
  276. #ifdef __cplusplus
  277. }
  278. #endif