Euphoria
torcurve.cc
Go to the documentation of this file.
1 #include "core/torcurve.h"
2 
3 #include <cmath>
4 
5 #include "base/numeric.h"
6 
7 
8 namespace eu::core
9 {
10 
11 
12 
13 float calc_tor_curve(float x, float a, float b, float c)
14 {
15  // pinch c near 0.5, smoothing out its effect
16  c = c < 0.5f
17  ? -c * c
18  : c * c
19  ;
20  x = max(0.0f, min(1.0f, x)); //clamp input to [0-1], behavior is undefined otherwise
21  const float s = std::exp(a); //could be any exponential like 2^a or 3^a, or just linear
22  const float s2 = 1.0f / s;
23  const float t = max(0.0f, min(1.0f, b));
24  const float u = c; //should normally be clamped but creates possibly useful results outside of the 0-1 range
25  const float eps = 0.00001f; //protect against div/0
26 
27  float res = 0.0f;
28  float c1 = 0.0f; //normal 1/x
29  float c2 = 0.0f; //flat-center
30  float c3 = 0.0f; //flat-end
31  if (x < t) {
32  c1 = (t * x) / (x + s * (t - x) + eps);
33  c2 = t - std::pow(1 / (t + eps), s2 - 1.0f) * std::pow(abs(x - t), s2);
34  c3 = std::pow(1.0f / (t + eps), s - 1.0f) * std::pow(x, s);
35  }
36  else {
37  c1 = (1.0f - t) * (x - 1.0f) / (1.0f - x - s * (t - x) + eps) + 1;
38  c2 = std::pow(1.0f / ((1.0f - t) + eps), s2 - 1.0f) * std::pow(abs(x - t), s2) + t;
39  c3 = 1.0f - std::pow(1 / ((1.0f - t) + eps), s - 1.0f) * std::pow(1.0f - x, s);
40  }
41  if (u <= 0) {
42  res = (-u) * c2 + (1.0f + u) * c1;
43  }
44  else {
45  res = (u)*c3 + (1.0f - u) * c1;
46  }
47 
48  // todo(Gustav): return 0 if inifinite
49  return res;
50 }
51 
52 
53 
54 
55 }
float calc_tor_curve(float x, float a, float b, float c)
A generalized curve formula.
Definition: torcurve.cc:13
constexpr float abs(float r)
Definition: numeric.h:8
size2f min(const size2f lhs, const size2f rhs)
Definition: size2.cc:140
size2f max(const size2f lhs, const size2f rhs)
Definition: size2.cc:149