Radium Engine  1.5.0
Math.hpp
1 #pragma once
2 
3 #include <Core/RaCore.hpp>
4 
5 #include <algorithm>
6 #include <cmath>
7 namespace Ra {
8 namespace Core {
9 
11 namespace Math {
13 constexpr Scalar Sqrt2 = Scalar( 1.41421356237309504880 ); // sqrt(2)
14 constexpr Scalar e = Scalar( 2.7182818284590452354 ); // e = exp(1).
15 constexpr Scalar Pi = Scalar( 3.14159265358979323846 ); // pi
16 constexpr Scalar InvPi = Scalar( 0.31830988618379067154 ); // 1/pi
17 constexpr Scalar PiDiv2 = Scalar( 1.57079632679489661923 ); // pi/2
18 constexpr Scalar PiDiv3 = Scalar( 1.04719755119659774615 ); // pi/3
19 constexpr Scalar PiDiv4 = Scalar( 0.78539816339744830962 ); // pi/4
20 constexpr Scalar PiDiv6 = Scalar( 0.52359877559829887307 ); // pi/6
21 constexpr Scalar PiMul2 = Scalar( 2 * Pi ); // 2*pi
22 constexpr Scalar toRad = Scalar( Pi / Scalar( 180.0 ) );
23 constexpr Scalar toDeg = Scalar( Scalar( 180.0 ) * InvPi );
24 
25 constexpr Scalar machineEps = std::numeric_limits<Scalar>::epsilon();
26 
28 
30 inline constexpr Scalar toRadians( Scalar a ) {
31  return toRad * a;
32 }
33 
35 inline constexpr Scalar toDegrees( Scalar a ) {
36  return toDeg * a;
37 }
38 
40 template <class T>
41 inline typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
42 areApproxEqual( T x, T y, T espilonBoostFactor = T( 10 ) ) {
43  return std::abs( x - y ) <= std::numeric_limits<T>::epsilon() * espilonBoostFactor
44  // unless the result is subnormal
45  || std::abs( x - y ) < std::numeric_limits<T>::min();
46 }
47 
52 template <typename Vector_Or_Scalar>
53 inline bool checkRange( const Vector_Or_Scalar& v, const Scalar& min, const Scalar& max ) {
54  using std::clamp; // by default, use clamp from the std library
55  return clamp( v, min, max ) == v;
56 }
57 
61 
63 template <typename T>
64 inline T ipow( const T& x, uint exp ) {
65  if ( exp == 0 ) { return T( 1 ); }
66  if ( exp == 1 ) { return x; }
67  T p = ipow( x, exp / 2 );
68  if ( ( exp % 2 ) == 0 ) { return p * p; }
69  else { return p * p * x; }
70 }
71 
74 namespace {
75 template <typename T, uint N>
76 struct IpowHelper {
77  static inline constexpr T pow( const T& x ) {
78  return ( N % 2 == 0 ) ? IpowHelper<T, N / 2>::pow( x ) * IpowHelper<T, N / 2>::pow( x )
79  : IpowHelper<T, N / 2>::pow( x ) * IpowHelper<T, N / 2>::pow( x ) * x;
80  }
81 };
82 
83 template <typename T>
84 struct IpowHelper<T, 1> {
85  static inline constexpr T pow( const T& x ) { return x; }
86 };
87 
88 template <typename T>
89 struct IpowHelper<T, 0> {
90  static inline constexpr T pow( const T& /*x*/ ) { return T( 1 ); }
91 };
92 } // namespace
94 template <uint N, typename T>
95 inline constexpr T ipow( const T& x ) {
96  return IpowHelper<T, N>::pow( x );
97 }
98 
99 template <typename T>
100 inline constexpr int signum( T x, std::true_type /*is_signed*/ ) {
101  return ( T( 0 ) < x ) - ( x < T( 0 ) );
102 }
103 
105 template <typename T>
106 inline constexpr int sign( const T& val ) {
107  return signum( val, std::is_signed<T>() );
108 }
109 
113 template <typename T>
114 inline constexpr T signNZ( const T& val ) {
115  return T( std::copysign( T( 1 ), val ) );
116 }
117 
119 template <typename T>
120 inline constexpr T saturate( T v ) {
121  return std::clamp( v, static_cast<T>( 0 ), static_cast<T>( 1 ) );
122 }
123 
125 template <typename T>
126 inline constexpr T lerp( const T& a, const T& b, Scalar t ) {
127  return ( 1 - t ) * a + t * b;
128 }
129 
131 template <typename T>
132 T smoothstep( T edge0, T edge1, T x ) {
133  using std::clamp;
134  T t = clamp( ( x - edge0 ) / ( edge1 - edge0 ), static_cast<T>( 0 ), static_cast<T>( 1 ) );
135  return t * t * ( 3.0 - 2.0 * t );
136 }
137 
138 template <typename T, template <typename, int...> typename M, int... p>
139 M<T, p...> smoothstep( T edge0, T edge1, M<T, p...> v ) {
140  return v.unaryExpr(
141  [edge0, edge1]( T x ) { return Ra::Core::Math::smoothstep( edge0, edge1, x ); } );
142 }
143 
144 } // namespace Math
145 } // namespace Core
146 } // namespace Ra
constexpr Scalar toRadians(Scalar a)
Useful functions.
Definition: Math.hpp:30
bool checkRange(const Vector_Or_Scalar &v, const Scalar &min, const Scalar &max)
Definition: Math.hpp:53
T smoothstep(T edge0, T edge1, T x)
As define by https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml.
Definition: Math.hpp:132
constexpr Scalar toDegrees(Scalar a)
Converts an angle from radians to degrees.
Definition: Math.hpp:35
constexpr Scalar Sqrt2
Mathematical constants casted to Scalar. Values taken from math.h.
Definition: Math.hpp:13
std::enable_if<!std::numeric_limits< T >::is_integer, bool >::type areApproxEqual(T x, T y, T espilonBoostFactor=T(10))
Compare two numbers such that |x-y| < espilon*epsilonBoostFactor.
Definition: Math.hpp:42
constexpr T lerp(const T &a, const T &b, Scalar t)
Returns the linear interpolation between a and b.
Definition: Math.hpp:126
constexpr T signNZ(const T &val)
Definition: Math.hpp:114
constexpr int sign(const T &val)
Returns the sign of any numeric type as { -1, 0, 1}.
Definition: Math.hpp:106
T ipow(const T &x, uint exp)
Run-time exponent version.
Definition: Math.hpp:64
constexpr T saturate(T v)
Clamps the value between 0 and 1.
Definition: Math.hpp:120
Derived::PlainMatrix clamp(const Eigen::MatrixBase< Derived > &v, const Eigen::MatrixBase< DerivedA > &min, const Eigen::MatrixBase< DerivedB > &max)
Component-wise clamp() function on a floating-point vector.
Definition: Cage.cpp:3