🛰️航天仿真算法库 SpaceAST 0.0.1
载入中...
搜索中...
未找到
Math.hpp
浏览该文件的文档.
1
20
21#pragma once
22
23#include "AstGlobal.h"
24#include "AstUtil/MathDegree.hpp"
25#include "AstUtil/Constants.h"
26#include <cmath>
27#include <cassert>
28#include <algorithm>
29#include <type_traits>
30#include <limits> // for std::numeric_limits<double>::quiet_NaN()
31
32AST_NAMESPACE_BEGIN
33
40#ifdef A_GCC // GCC 内建 sincos 函数
41// #pragma message("Using GCC built-in sincos function")
42using ::sincos;
43
44#else
45
50A_ALWAYS_INLINE void sincos (double x, double *psin, double *pcos)
51{
52 *psin = sin(x);
53 *pcos = cos(x);
54}
55
56#endif
57
58
60class SinCos {
61public:
62 A_ALWAYS_INLINE
63 double sin() const { return sin_; }
64 A_ALWAYS_INLINE
65 double& sin() { return sin_; }
66 A_ALWAYS_INLINE
67 double cos() const { return cos_; }
68 A_ALWAYS_INLINE
69 double& cos() { return cos_; }
70public:
71 double sin_;
72 double cos_;
73};
74
75
79A_ALWAYS_INLINE SinCos sincos(double x)
80{
81 SinCos sc;
82 sincos(x, &sc.sin_, &sc.cos_);
83 return sc;
84}
85
86
87
89template<typename Scalar>
90Scalar aMax(Scalar a, Scalar b)
91{
92 return a > b ? a : b;
93}
94
96template<typename Scalar>
97Scalar aMin(Scalar a, Scalar b)
98{
99 return a < b ? a : b;
100}
101
102using std::max;
103using std::min;
104
110template<typename T>
111A_CONSTEXPR_CXX14 const T& clamp(const T& val, const T& low, const T& high)
112{
113 #ifdef A_CXX14
114 assert(low <= high && "low must be less than or equal to high");
115 if(val < low){
116 return low;
117 }
118 if(val > high){
119 return high;
120 }
121 return val;
122 #else
123 return (val < low) ? low : ((val > high) ? high : val);
124 #endif
125}
126
127
131A_ALWAYS_INLINE double asinSafe(double x)
132{
133 return std::asin(clamp(x, -1.0, 1.0));
134}
135
139A_ALWAYS_INLINE double acosSafe(double x)
140{
141 return std::acos(clamp(x, -1.0, 1.0));
142}
143
147A_ALWAYS_INLINE double sqrtSafe(double x)
148{
149 return std::sqrt((std::max)(x, 0.0));
150}
151
154template<typename Scalar>
155Scalar square(Scalar x)
156{
157 return x * x;
158}
159
160
165A_ALWAYS_INLINE double aNormalizeAngleStart(double angle, double start)
166{
167 return angle - floor((angle - start) / kTwoPI) * kTwoPI;
168}
169
170
175A_ALWAYS_INLINE double aNormalizeAngle(double angle, double center)
176{
177 return aNormalizeAngleStart(angle, center - kPI);
178}
179
180
184A_ALWAYS_INLINE double aNormalizeAngle0To2Pi(double angle)
185{
186 return aNormalizeAngleStart(angle, 0);
187}
188
192A_ALWAYS_INLINE double aNormalizeAngleNegPiToPi(double angle)
193{
194 return aNormalizeAngleStart(angle, -kPI);
195}
196
200A_ALWAYS_INLINE double aNormalizeAngleNeg2PiTo0(double angle)
201{
202 return aNormalizeAngleStart(angle, -kTwoPI);
203}
204
205
207namespace propagate_nan
208{
210 A_ALWAYS_INLINE double (min)(double a, double b)
211 {
212 if(a <= b)
213 return a;
214 if(b <= a)
215 return b;
216 return std::numeric_limits<double>::quiet_NaN();
217 }
218
220 A_ALWAYS_INLINE double (max)(double a, double b)
221 {
222 if(a >= b)
223 return a;
224 if(b >= a)
225 return b;
226 return std::numeric_limits<double>::quiet_NaN();
227 }
228
229 // SWIG 无法解析 has_minus 中的 decltype SFINAE 检测,以下内部模板暂不暴露给 SWIG
230#ifndef SWIG
231 // -------------------- 类型标记:类型是否允许使用减法,需要用户通过类型特化 allow_efficient_minus 来明确允许 --------------------
232 template <typename T>
233 struct allow_efficient_minus : std::false_type {};
234
235 // -------------------- 工具:检测是否存在 operator- --------------------
236 template <typename T>
238 {
239 template <typename U>
240 static auto test(int) -> decltype(std::declval<U>() - std::declval<U>(), std::true_type());
241 template <typename U>
242 static std::false_type test(...);
243
244 static constexpr bool value = decltype(test<T>(0))::value;
245 };
246
247 // -------------------- 类型标记:是否使用减法 --------------------
248 template <typename T>
250 {
251 static constexpr bool value = allow_efficient_minus<T>::value && has_minus<T>::value;
252 };
253
254 template<typename T>
255 typename std::enable_if<!use_efficient_minus<T>::value,const T&>::type
256 (min)(const T& a, const T& b)
257 {
258 // 不支持 operator- 的类型,直接比较大小
259 if(a <= b)
260 return a;
261 if(b <= a)
262 return b;
263 if(a != a)
264 return a;
265 return b;
266 }
267 template <typename T>
268 typename std::enable_if<use_efficient_minus<T>::value, const T&>::type
269 (min)(const T& a, const T& b) {
270 // 支持 operator- 的类型,使用减法比较大小
271 auto diff = a - b; // 注意:这里会构造临时对象
272 if (diff <= 0) return a; // a <= b
273 if (diff >= 0) return b; // a >= b
274 if(a != a)
275 return a;
276 return b;
277 }
278
279 template<typename T>
280 typename std::enable_if<!use_efficient_minus<T>::value,const T&>::type
281 (max)(const T& a, const T& b)
282 {
283 // 不支持 operator- 的类型,直接比较大小
284 if(a >= b)
285 return a;
286 if(b >= a)
287 return b;
288 if(a != a)
289 return a;
290 return b;
291 }
292 template <typename T>
293 typename std::enable_if<use_efficient_minus<T>::value, const T&>::type
294 (max)(const T& a, const T& b)
295 {
296 // 支持 operator- 的类型,使用减法比较大小
297 auto diff = a - b; // 注意:这里会构造临时对象
298 if (diff >= 0) return a; // a >= b
299 if (diff <= 0) return b; // a <= b
300 if(a != a)
301 return a;
302 return b;
303 }
304#endif // !SWIG
305}
306
309AST_NAMESPACE_END
包含 sin(x) 和 cos(x) 值的结构体
定义 Math.hpp:60
constexpr double kTwoPI
2*PI
定义 Constants.h:54
A_ALWAYS_INLINE double sqrtSafe(double x)
安全平方根,参数自动箝位到 [0, +∞]
定义 Math.hpp:147
A_ALWAYS_INLINE double aNormalizeAngle0To2Pi(double angle)
将角度量规范化到 0 到 2π 范围
定义 Math.hpp:184
A_ALWAYS_INLINE double asinSafe(double x)
安全反正弦,参数自动箝位到 [-1, 1]
定义 Math.hpp:131
A_ALWAYS_INLINE double aNormalizeAngleNegPiToPi(double angle)
将角度量规范化到 -π 到 π 范围
定义 Math.hpp:192
A_CONSTEXPR_CXX14 const T & clamp(const T &val, const T &low, const T &high)
对值进行范围限制
定义 Math.hpp:111
Scalar aMax(Scalar a, Scalar b)
计算两个数中的较大值
定义 Math.hpp:90
constexpr double kPI
PI
定义 Constants.h:53
A_ALWAYS_INLINE double aNormalizeAngleNeg2PiTo0(double angle)
将角度量规范化到 -2π 到 0 范围
定义 Math.hpp:200
Scalar aMin(Scalar a, Scalar b)
计算两个数中的较小值
定义 Math.hpp:97
A_ALWAYS_INLINE double aNormalizeAngleStart(double angle, double start)
将角度量规范化到指定起始范围
定义 Math.hpp:165
A_ALWAYS_INLINE double aNormalizeAngle(double angle, double center)
将角度量规范化到指定中心范围
定义 Math.hpp:175
Scalar square(Scalar x)
计算平方
定义 Math.hpp:155
A_ALWAYS_INLINE double acosSafe(double x)
安全反余弦,参数自动箝位到 [-1, 1]
定义 Math.hpp:139
A_ALWAYS_INLINE void sincos(double x, double *psin, double *pcos)
计算 sin(x) 和 cos(x) 值
定义 Math.hpp:50
Unit T
特斯拉
定义 Unit.cpp:492