33# define A_LIKELY(expr) (expr)
37typedef std::array<double, 3> array3d;
38typedef std::array<double, 6> array6d;
46template<
typename _Scalar,
size_t Row,
size_t Col>
60inline std::pair<double, double> twoSum(
double a,
double b) {
63 double e = (a - (
s - t)) + (b - t);
67inline double eps(
double t)
71 return pow(2.0, -1075.0);
74 return pow(2.0, -53.0 + floor(log(fabs(t)) / log(2.0)));
78#if defined _MSC_VER || __cplusplus >= 201703L
84template <
typename Container>
85auto size(
const Container& vec)
noexcept
86 ->
decltype(vec.size())
91template <
class _Scalar,
size_t N>
92constexpr size_t size(
const _Scalar (&)[
N])
noexcept
101template<
typename _Scalar>
113typename std::enable_if<std::is_arithmetic<T>::value, T>::type
116 return x - int(x / y) * y;
121inline typename std::enable_if<std::is_floating_point<T>::value, T>::type
124 if (y == 0)
return x;
125 return x - floor(x / y) * y;
131typename std::enable_if<std::is_arithmetic<T>::value, T>::type
140inline double cot(
double a)
142 return cos(a) / sin(a);
145inline double acot(
double a)
152template<
typename Container1,
typename Container2>
153inline double dot(
const Container1& vec1,
const Container2& vec2)
155 assert (size(vec1) == size(vec2));
157 size_t s = size(vec2);
158 for (
size_t i = 0; i <
s; i++)
160 retval += vec1[i] * vec2[i];
166template<
size_t N1,
size_t N2>
167inline double dot(
const double(&vec1)[N1],
const double(&vec2)[N2])
169 static_assert(N1 == N2,
"dot product requires two vectors of the same size");
171 for (
size_t i = 0; i < N1; i++)
173 retval += vec1[i] * vec2[i];
179inline double dot(
const double* vec1,
const double* vec2,
size_t N)
182 for (
size_t i = 0; i <
N; i++)
184 retval += vec1[i] * vec2[i];
189inline double dot3(
const double* vec1,
const double* vec2)
191 return dot(vec1, vec2, 3);
197template<
typename Vector3D1,
typename Vector3D2>
198inline auto cross(
const Vector3D1& vec1,
const Vector3D2& vec2)
199 ->
typename std::enable_if<!std::is_pointer<Vector3D1>::value && !std::is_pointer<Vector3D2>::value, Vector3D1>::type
201 assert (size(vec1) >= 3 && size(vec2) >= 3);
204 vec1[1] * vec2[2] - vec1[2] * vec2[1],
205 vec1[2] * vec2[0] - vec1[0] * vec2[2],
206 vec1[0] * vec2[1] - vec1[1] * vec2[0]
210inline void cross(
double* res,
const double* vec1,
const double* vec2)
212 res[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
213 res[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
214 res[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
220template<
size_t N1,
size_t N2>
221inline std::array<double, 3> cross(
const double (&vec1)[N1],
const double (&vec2)[N2])
223 static_assert(N1 >= 3,
"cross product requires vectors of at least size 3");
224 static_assert(N2 >= 3,
"cross product requires vectors of at least size 3");
226 return std::array<double, 3>{
227 vec1[1] * vec2[2] - vec1[2] * vec2[1],
228 vec1[2] * vec2[0] - vec1[0] * vec2[2],
229 vec1[0] * vec2[1] - vec1[1] * vec2[0]
234inline std::array<double, 3> cross3(
const double* vec1,
const double* vec2)
236 return std::array<double, 3>{
237 vec1[1] * vec2[2] - vec1[2] * vec2[1],
238 vec1[2] * vec2[0] - vec1[0] * vec2[2],
239 vec1[0] * vec2[1] - vec1[1] * vec2[0]
248 for (
size_t i = 0; i <
N; i++)
250 sumsq += vec[i] * vec[i];
256template<
typename Vector>
258 ->
typename std::enable_if<!std::is_pointer<Vector>::value,
double>::type
261 for (
const auto& val : vec) {
271 for (
size_t i = 0; i <
N; i++)
273 sumsq += vec[i] * vec[i];
281inline double norm(
const double* vec,
size_t N)
287template<
typename Vector>
288inline auto norm(
const Vector& vec)
289 ->
typename std::enable_if<!std::is_pointer<Vector>::value,
double>::type
297inline double norm(
const double (&vec)[N])
299 return sqrt(squaredNorm(vec));
308 double mag =
norm(vec,
N);
309 if (A_LIKELY(mag != 0)){
310 for (
size_t i = 0; i <
N; i++)
319template<
typename Vector>
321->
typename std::enable_if<!std::is_pointer<Vector>::value,
double>::type
323 double mag =
norm(vec);
324 if (A_LIKELY(mag != 0)){
325 for (
auto& val : vec) {
337 double mag =
norm(vec);
338 if (A_LIKELY(mag != 0)){
339 for (
size_t i = 0; i <
N; i++)
351template<
typename Vector>
353->
typename std::enable_if<!std::is_pointer<Vector>::value, Vector>::type
355 Vector retval{ vec };
363inline std::array<double, N>
normalized(
double (&vec)[N])
365 std::array<double, N> retval;
366 double mag =
norm(vec);
367 if (A_LIKELY(mag != 0)){
368 for (
size_t i = 0; i <
N; i++)
370 retval[i] = vec[i] / mag;
374 for (
size_t i = 0; i <
N; i++) {
382inline std::array<double, N>
normalized(
const double* vec)
384 std::array<double, N> retval;
385 double mag =
norm(vec, N);
386 if (A_LIKELY(mag != 0)){
387 for (
size_t i = 0; i <
N; i++)
389 retval[i] = vec[i] / mag;
393 for (
size_t i = 0; i <
N; i++) {
405 static auto test(
int) ->
decltype(
406 std::declval<U>()[0],
407 size(std::declval<U>()),
412 static std::false_type test(...);
415 static constexpr bool value =
decltype(test<T>(0))::value;
421#define _AST_DEF_OP_SV(OP) \
422template<typename Scalar, typename Vector> \
423inline auto operator OP(Scalar scalar, const Vector& vec) \
424-> typename std::enable_if<std::is_arithmetic<Scalar>::value && is_vector_like<Vector>::value, Vector>::type \
426 Vector retval{ vec }; \
427 size_t s = size(vec); \
428 for (size_t i = 0; i < s; i++) \
430 retval[i] OP##= scalar; \
436#define _AST_DEF_OP_VS(OP) \
437template<typename Vector, typename Scalar> \
438inline auto operator OP(const Vector& vec, Scalar scalar) \
439-> typename std::enable_if<std::is_arithmetic<Scalar>::value && is_vector_like<Vector>::value, Vector>::type \
441 Vector retval{ vec }; \
442 size_t s = size(vec); \
443 for (size_t i = 0; i < s; i++) \
445 retval[i] OP##= scalar; \
451#define _AST_DEF_OP_VV(OP) \
452template<typename Vector1, typename Vector2> \
453inline auto operator OP(const Vector1& vec1, const Vector2& vec2)\
454-> typename std::enable_if<is_vector_like<Vector1>::value && is_vector_like<Vector2>::value, Vector1>::type \
456 assert(size(vec1) == size(vec2)); \
457 Vector1 retval{ vec1 }; \
458 size_t s = size(vec1); \
459 for (size_t i = 0; i < s; i++) \
461 retval[i] OP##= vec2[i]; \
467#define _AST_DEF_OP(OP) \
493template<
size_t N1,
size_t N2>
494inline std::array<double, N1> operator+(
const double (&vec1)[N1],
const double (&vec2)[N2])
496 static_assert(N1 == N2,
"plus operator requires vectors of the same dimension");
497 std::array<double, N1> retval{};
498 for (
size_t i = 0; i < N1; i++)
500 retval[i] = vec1[i] + vec2[i];
510template<
typename _Scalar,
size_t I,
size_t J,
size_t K>
511std::array<std::array<_Scalar, K>, I>
mtimes(
512 const _Scalar(&left)[I][J],
513 const _Scalar(&right)[J][K]
516 std::array<std::array<_Scalar, K>, I> retval;
517 for (
size_t i = 0; i < I; i++)
519 for (
size_t k = 0; k < K ; k++) {
521 for (
size_t j = 0; j < J; j++)
523 value += left[i][j] * right[j][k];
525 retval[i][k] = value;
533#define _ASTMATH _AST math::
541template<
typename _Scalar,
size_t I,
size_t J,
size_t K>
542MatrixMN<_Scalar, I, K> operator* (
543 const MatrixMN<_Scalar, I, J>& left,
544 const MatrixMN<_Scalar, J, K>& right
547 MatrixMN<_Scalar, I, K> retval;
548 for (
size_t i = 0; i < I; i++)
550 for (
size_t k = 0; k < K; k++) {
552 for (
size_t j = 0; j < J; j++)
554 value += left(i, j) * right(j, k);
556 retval(i, k) = value;
563template<
typename _Scalar,
size_t I,
size_t J>
564VectorN<_Scalar, I> operator*(
565 const MatrixMN<_Scalar, I, J>& left,
566 const VectorN<_Scalar, J>& right
569 VectorN<_Scalar, I> result;
570 for (
size_t i = 0; i < I; ++i) {
572 for (
size_t j = 0; j < J; ++j) {
573 sum += left(i, j) * right[j];
580template<
typename _Scalar,
size_t I,
size_t J>
581VectorN<_Scalar, J> operator*(
582 const VectorN<_Scalar, I>& left,
583 const MatrixMN<_Scalar, I, J>& right
586 VectorN<_Scalar, J> result{};
587 for(
size_t i=0;i<I;++i){
588 for(
size_t j=0;j<J;++j){
589 result[j] += left[i] * right(i, j);
598A_CONSTEXPR_CXX14
const T& clamp(
const T& val,
const T& low,
const T& high)
601 assert(low <= high &&
"low must be less than or equal to high");
610 return (val < low) ? low : ((val > high) ? high : val);
#define _AST_DEF_OP_SV(OP)
定义 MathOperator.hpp:421
int sign(_Scalar val)
sign
定义 MathOperator.hpp:102
double cot(double a)
cot acot
定义 MathOperator.hpp:140
double norm(const double *vec, size_t N)
norm
定义 MathOperator.hpp:281
double dot(const Container1 &vec1, const Container2 &vec2)
dot
定义 MathOperator.hpp:153
std::array< std::array< _Scalar, K >, I > mtimes(const _Scalar(&left)[I][J], const _Scalar(&right)[J][K])
矩阵乘法
定义 MathOperator.hpp:511
auto normalized(const Vector &vec) -> typename std::enable_if<!std::is_pointer< Vector >::value, Vector >::type
normalized
定义 MathOperator.hpp:352
double normalize(double *vec, size_t N)
normalize
定义 MathOperator.hpp:306
double squaredNorm(const double *vec, size_t N)
squaredNorm
定义 MathOperator.hpp:245