#pragma once
|
|
|
|
#include "gp_config.hpp"
|
|
|
|
#include "gp/algorithms/repeat.hpp"
|
|
|
|
namespace gp {
|
|
template<typename T>
|
|
T lerp(T input, T low, T high) {
|
|
return low + (high - low) * input;
|
|
}
|
|
template<typename T>
|
|
T lextrap(T input, T low, T high) {
|
|
return (input - low) / (high - low);
|
|
}
|
|
|
|
template<typename T, size_t fixed_passes = 16>
|
|
T fixed_sqrt(T value) {
|
|
gp_config::assertion(value >= 0, "trying to compute square root of negative number");
|
|
if(value == 0) return 0;
|
|
T ret = value / 2;
|
|
T tmp;
|
|
|
|
gp::repeat(fixed_passes, [&](){
|
|
tmp = ret;
|
|
ret = (value / tmp + tmp) / 2;
|
|
});
|
|
|
|
return ret;
|
|
}
|
|
|
|
template<typename T, size_t cap_passes = 16>
|
|
T epsilon_sqrt(T value) {
|
|
gp_config::assertion(value >= 0, "trying to compute square root of negative number");
|
|
if(value == 0) return 0;
|
|
T ret = value / 2;
|
|
T tmp;
|
|
constexpr T epsilon = gp_config::rendering::epsilon;
|
|
size_t cnt = 0;
|
|
while(
|
|
!(
|
|
(ret+epsilon)*ret > value
|
|
&& (ret-epsilon)*ret < value
|
|
)
|
|
&& cnt < cap_passes
|
|
){
|
|
tmp = ret;
|
|
ret = (value / tmp + tmp) / 2;
|
|
++cnt;
|
|
};
|
|
|
|
return ret;
|
|
}
|
|
|
|
template<typename T, size_t cap_passes = 16>
|
|
T stable_sqrt(T value) {
|
|
gp_config::assertion(value >= 0, "trying to compute square root of negative number");
|
|
if(value == 0) return 0;
|
|
T ret = value / 2;
|
|
T tmp;
|
|
while(ret != tmp){
|
|
tmp = ret;
|
|
ret = (value / tmp + tmp) / 2;
|
|
};
|
|
|
|
return ret;
|
|
}
|
|
}
|