MathLib
Loading...
Searching...
No Matches
Functions.hpp
Go to the documentation of this file.
1#pragma once
2
8#include <algorithm>
9
16namespace Math
17{
18
25template <class Type>
26constexpr inline Type lerp(Type input_lower_bound, Type input_upper_bound, float percentage_zero_to_one)
27{
28 // C++ 20 has std::lerp() in <cmath>, so use that by default
29 if constexpr (std::is_floating_point<Type>::value)
30 return std::lerp(input_lower_bound, input_upper_bound, percentage_zero_to_one);
31 else
32 return (input_upper_bound - input_lower_bound) * percentage_zero_to_one + input_lower_bound;
33}
34
45template <class Type>
46constexpr inline Type mix(Type input_lower_bound, Type input_upper_bound, float percentage_zero_to_one)
47{
48 return Math::lerp(input_lower_bound, input_upper_bound, percentage_zero_to_one);
49}
50
59template <class Type>
60constexpr inline Type inverse_lerp(Type input_lower_bound, Type input_upper_bound, Type value_between)
61{
62 return (value_between - input_lower_bound) / (input_upper_bound - input_lower_bound);
63}
64
79template <class Type>
80constexpr inline Type remap(Type input_value, Type orig_range_min, Type orig_range_max, Type new_range_min, Type new_range_max)
81{
82 return lerp(new_range_min, new_range_max, inverse_lerp(orig_range_min, orig_range_max, input_value));
83}
84
93template <class Type>
94constexpr inline const Type &saturate(const Type &value, const Type &lower_bound, const Type &upper_bound)
95{
96 return std::clamp( value, lower_bound, upper_bound );
97}
98
99template <class Type>
100constexpr inline Type step(Type y, Type x)
101{
102 return (x >= y) ? 1 : 0;
103}
104
105constexpr inline float smoothstep(float input_value, float left_edge = 0.0f, float right_edge = 1.0f)
106{
107 // Scale and clamp to 0..1 range
108 input_value = std::clamp<float>((input_value - left_edge) / (right_edge - left_edge), 0.0f, 1.0f);
109
110 return input_value * input_value * (3.0f - 2.0f * input_value);
111}
112
113// Second-order smoothstep function
114template <class Type>
115constexpr inline Type smootherstep(Type input_value, Type left_edge, Type right_edge)
116{
117 // Scale and clamp to 0..1 range
118 input_value = std::clamp((input_value - left_edge) / (right_edge - left_edge), Type{0}, Type{1});
119 if constexpr (std::is_same<Type, float>::value)
120 return input_value * input_value * input_value * (input_value * (6.0f * input_value - 15.0f) + 10.0f);
121 else
122 return input_value * input_value * input_value * (input_value * (6.0 * input_value - 15.0) + 10.0);
123}
124
125template <class Type = float>
126constexpr inline Type smoothstep_generalized(Type input_value, Type left_edge = 0, Type right_edge = 1, int Order = 1)
127{
128 // Scale and clamp to 0..1 range
129 input_value = std::clamp<Type>((input_value - left_edge) / (right_edge - left_edge), Type{0}, Type{1});
130
131 // Order of 0 mathematically works out to just the clamp
132 if (Order == 0)
133 return input_value;
134
135 Type accumulation = 0;
136
137 for (int n = 0; n <= Order; ++n)
138 {
139 Type part0 = std::pow( static_cast<Type>(-1), static_cast<Type>(n));
140 int part1 = Combinatorics::binomial_coefficient( Order + n, n );
141 int part2 = Combinatorics::binomial_coefficient( 2 * Order + 1, Order - n );
142 Type part3 = std::pow( input_value, static_cast<Type>(Order + n + 1) );
143
144 accumulation += part0 * static_cast<Type>(part1) * static_cast<Type>(part2) * part3;
145 }
146 return accumulation;
147}
148
149template <class Type = float>
150constexpr inline Type inverse_smoothstep(Type input_value)
151{
152 return Type{0.5} - std::sin( std::asin(Type{1.0} - Type{2.0} * std::clamp<Type>(input_value, Type{0}, Type{1})) / Type{3.0} );
153}
154
155template <class Type>
156Type fract(Type input)
157{
158 return std::modf(input);
159}
160
161}
constexpr int binomial_coefficient(int row, int column)
Definition Angle.hpp:16
constexpr Type smoothstep_generalized(Type input_value, Type left_edge=0, Type right_edge=1, int Order=1)
constexpr Type lerp(Type input_lower_bound, Type input_upper_bound, float percentage_zero_to_one)
Definition Functions.hpp:26
constexpr Type remap(Type input_value, Type orig_range_min, Type orig_range_max, Type new_range_min, Type new_range_max)
Definition Functions.hpp:80
Type fract(Type input)
constexpr Type inverse_lerp(Type input_lower_bound, Type input_upper_bound, Type value_between)
Definition Functions.hpp:60
constexpr float smoothstep(float input_value, float left_edge=0.0f, float right_edge=1.0f)
constexpr const Type & saturate(const Type &value, const Type &lower_bound, const Type &upper_bound)
Definition Functions.hpp:94
constexpr Type smootherstep(Type input_value, Type left_edge, Type right_edge)
constexpr Type mix(Type input_lower_bound, Type input_upper_bound, float percentage_zero_to_one)
Definition Functions.hpp:46
constexpr Type step(Type y, Type x)
constexpr Type inverse_smoothstep(Type input_value)