GA::kit v0.3
G&A's in-house C++ application framework
Loading...
Searching...
No Matches
math.h
Go to the documentation of this file.
1#pragma once
2#include "ga/defines.h"
3#include "glm/glm.hpp"
4#include "glm/gtx/matrix_decompose.hpp" // needed for matrix decomposition
5#include "glm/gtx/quaternion.hpp"
6#include <algorithm>
7#include <limits>
8
9#ifdef GA_OPENFRAMEWORKS
10#include "ofRectangle.h"
11#endif
12
13namespace ga {
14
15namespace math {
16
17 const double pi = 4. * std::atan( 1. ); // tan(1/4 PI) = 1
18 const double halfPi = pi * .5;
19
20 const double radToDegFactor = 180. / math::pi; // degrees = 180/pi * radians
21 const double degToRadFactor = math::pi / 180.; // radians = pi/180 * degrees
22
23} // namespace math
24
25// pull into ga namespace:
26using glm::mat2;
27using glm::mat2x3;
28using glm::mat3;
29using glm::mat4;
30using glm::quat;
31using glm::vec2;
32using glm::vec3;
33using glm::vec4;
34
35template <typename T>
36inline T toDegrees( const T& radians )
37{
38 return math::radToDegFactor * radians;
39}
40
41inline double toDegrees( const double& radians )
42{
43 return math::radToDegFactor * radians;
44}
45
46template <typename T>
47inline T toRadians( const T& degrees )
48{
49 return math::degToRadFactor * degrees;
50}
51
52inline double toRadians( const double& degrees )
53{
54 return math::degToRadFactor * degrees;
55}
56
63struct Rect
64{
65 Rect() {}
66 Rect( float xPos, float yPos, float width, float height )
67 : x( xPos )
68 , y( yPos )
69 , w( width )
70 , h( height )
71 {
72 }
73 Rect( const vec2& ptA, const vec2& ptB )
74 {
75 auto sz = ptB - ptA;
76 x = ptA.x;
77 y = ptA.y;
78 w = sz.x;
79 h = sz.y;
80 }
81#ifdef GA_OPENFRAMEWORKS
82 Rect( const ofRectangle& rect )
83 : x( rect.x )
84 , y( rect.y )
85 , w( rect.width )
86 , h( rect.height )
87 {
88 }
89#endif
90
91 float x, y, w, h;
92
93 vec2 position() const { return vec2 { x, y }; }
94 vec2 size() const { return vec2 { w, h }; }
95 float area() const { return std::abs( w * h ); }
96 vec2 min() const { return vec2( std::min( x, x + w ), std::min( y, y + h ) ); } // same as position(), unless width or height < 0
97 vec2 max() const { return vec2( std::max( x, x + w ), std::max( y, y + h ) ); }
98 bool contains( const vec2& pt ) const
99 {
100 vec2 a = min();
101 vec2 b = max();
102 return pt.x >= a.x && pt.y >= a.y && pt.x <= b.x && pt.y <= b.y;
103 }
104};
105
106// /**
107// * @brief A 2D axis-aligned bounding box.
108// *
109// */
110// struct Bounds2D
111// {
112// vec2 min, max;
113// bool isInside( vec2
114// vec2 center() const { return ( min + max ) * .5f; }
115// float width() const { return max.x - min.x; }
116// float height() const { return max.y - min.y; }
117// };
118
124{
125 vec3 min, max;
126 vec3 center() const { return ( min + max ) * .5f; }
127 vec3 size() const { return max - min; }
128 float width() const { return max.x - min.x; }
129 float height() const { return max.y - min.y; }
130 float depth() const { return max.z - min.z; }
131};
132
138template <typename T>
139inline const T& clamp( const T& val, const T& min, const T& max )
140{
141 return ( val < min ) ? min
142 : ( val > max ) ? max
143 : val;
144}
145
153template <typename T>
154inline T map( const T& val, const T& inMin, const T& inMax, const T& outMin, const T& outMax, bool bClamp = false )
155{
156 T r = val;
157 try { // check for 0 divide
158 r = ( val - inMin ) / ( inMax - inMin ) * ( outMax - outMin ) + outMin;
159 } catch ( ... ) {
160 }
161 return bClamp ? clamp( r, outMin, outMax ) : r;
162}
163
164inline float map(const float& val, const float& inMin, const float& inMax, const float& outMin, const float& outMax, bool bClamp = false)
165{
166 float r = val;
167 try { // check for 0 divide
168 r = (val - inMin) / (inMax - inMin) * (outMax - outMin) + outMin;
169 }
170 catch (...) {
171 }
172 return bClamp ? clamp(r, outMin, outMax) : r;
173}
174
175
176// linear interpolations
177// ----------------------
178
179template <typename T>
180inline T lerp( const T& a, const T& b, const T& pct )
181{
182 return ( b - a ) * pct + a;
183}
184
185template <typename T>
186inline T lerp( const T& a, const T& b, float pct )
187{
188 return ( b - a ) * pct + a;
189}
190
191inline float lerp( float a, float b, float pct )
192{
193 return ( b - a ) * pct + a;
194}
195
196inline quat lerp( const quat& a, const quat& b, float pct )
197{
198 return slerp( a, b, pct );
199}
200
201// quaternion rotation
202inline quat slerp( const quat& a, const quat& b, float pct )
203{
204 return glm::slerp( a, b, pct ); // spherical lerp
205}
206
207// cubic bezier curve - https://cubic-bezier.com/
208inline float cubicBezier( float x, float x1, float y1, float x2, float y2 )
209{
210 if ( x == 0. )
211 return 0.;
212 if ( x == 1. )
213 return 1.;
214
215 // from http://www.flong.com/texts/code/shapers_bez/
216
217 float y0a = 0.; // initial y
218 float x0a = 0.; // initial x
219 float y1a = y1; // 1st influence y
220 float x1a = x1; // 1st influence x
221 float y2a = y2; // 2nd influence y
222 float x2a = x2; // 2nd influence x
223 float y3a = 1.; // final y
224 float x3a = 1.; // final x
225
226 float A = x3a - 3.f * x2a + 3.f * x1a - x0a;
227 float B = 3.f * x2a - 6.f * x1a + 3.f * x0a;
228 float C = 3.f * x1a - 3.f * x0a;
229 float D = x0a;
230
231 float E = y3a - 3.f * y2a + 3.f * y1a - y0a;
232 float F = 3.f * y2a - 6.f * y1a + 3.f * y0a;
233 float G = 3.f * y1a - 3.f * y0a;
234 float H = y0a;
235
236 auto slopeFromT = []( float t, float A, float B, float C ) -> float {
237 return 1.f / ( 3.f * A * t * t + 2.f * B * t + C ); // dtdx
238 };
239 auto xFromT = []( float t, float A, float B, float C, float D ) -> float {
240 return A * ( t * t * t ) + B * ( t * t ) + C * t + D;
241 };
242 auto yFromT = []( float t, float E, float F, float G, float H ) -> float {
243 return E * ( t * t * t ) + F * ( t * t ) + G * t + H;
244 };
245
246 // Solve for t given x (using Newton-Raphelson), then solve for y given t.
247 // Assume for the first guess that t = x.
248 float currentt = x;
249 int nRefinementIterations = 5;
250 for ( int i = 0; i < nRefinementIterations; i++ ) {
251 float currentx = xFromT( currentt, A, B, C, D );
252 float currentslope = slopeFromT( currentt, A, B, C );
253 currentt -= ( currentx - x ) * ( currentslope );
254 currentt = clamp( currentt, 0.f, 1.f );
255 }
256
257 return yFromT( currentt, E, F, G, H );
258}
259
260// templated interpolation
261// use an ease function to interpolate from one value to another
262template <typename T>
263inline T interpolate( const T& a, const T& b, float pct, std::function<float( float )> easeFn, bool bClamp = false )
264{
265 pct = bClamp ? ga::clamp( easeFn( pct ), 0.f, 1.f ) : easeFn( pct ); // use easing on the pct
266 return ga::lerp( a, b, pct ); // then lerp based on eased pct
267}
268
269} // namespace ga
const double pi
Definition: math.h:17
const double degToRadFactor
Definition: math.h:21
const double halfPi
Definition: math.h:18
const double radToDegFactor
Definition: math.h:20
Definition: color.h:9
std::function< float(float)> easeFn(const EaseType &type)
Definition: easing.h:102
T map(const T &val, const T &inMin, const T &inMax, const T &outMin, const T &outMax, bool bClamp=false)
Map a value from one range to another.
Definition: math.h:154
float cubicBezier(float x, float x1, float y1, float x2, float y2)
Definition: math.h:208
T interpolate(const T &a, const T &b, float pct, std::function< float(float)> easeFn, bool bClamp=false)
Definition: math.h:263
T toRadians(const T &degrees)
Definition: math.h:47
quat slerp(const quat &a, const quat &b, float pct)
Definition: math.h:202
T toDegrees(const T &radians)
Definition: math.h:36
T lerp(const T &a, const T &b, const T &pct)
Definition: math.h:180
const T & clamp(const T &val, const T &min, const T &max)
Clamp a value between a minimum and a maximum.
Definition: math.h:139
A 3D axis-aligned bounding box.
Definition: math.h:124
vec3 max
Definition: math.h:125
vec3 size() const
Definition: math.h:127
float height() const
Definition: math.h:129
vec3 center() const
Definition: math.h:126
vec3 min
Definition: math.h:125
float width() const
Definition: math.h:128
float depth() const
Definition: math.h:130
A 2D axis-aligned rectangle, with x,y (float) position and w,h (float) size components.
Definition: math.h:64
vec2 position() const
Definition: math.h:93
float y
Definition: math.h:91
vec2 max() const
Definition: math.h:97
Rect(float xPos, float yPos, float width, float height)
Definition: math.h:66
float x
Definition: math.h:91
vec2 size() const
Definition: math.h:94
Rect()
Definition: math.h:65
Rect(const vec2 &ptA, const vec2 &ptB)
Definition: math.h:73
float h
Definition: math.h:91
float area() const
Definition: math.h:95
vec2 min() const
Definition: math.h:96
float w
Definition: math.h:91
bool contains(const vec2 &pt) const
Definition: math.h:98