diff options
| author | a1xd <[email protected]> | 2021-09-22 20:49:04 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-09-22 20:49:04 -0400 |
| commit | 8a4b6f57758338d5537d4671184099a4728a8cdd (patch) | |
| tree | df36529a344d5d21ff11f5ba021ec80afb4b68a4 /common/accel-jump.hpp | |
| parent | Merge pull request #87 from matthewstrasiotto/streamer_mode (diff) | |
| parent | improve converter + docs (diff) | |
| download | rawaccel-8a4b6f57758338d5537d4671184099a4728a8cdd.tar.xz rawaccel-8a4b6f57758338d5537d4671184099a4728a8cdd.zip | |
Merge pull request #105 from a1xd/1.5.x
v1.5
Diffstat (limited to 'common/accel-jump.hpp')
| -rw-r--r-- | common/accel-jump.hpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/common/accel-jump.hpp b/common/accel-jump.hpp new file mode 100644 index 0000000..95fa461 --- /dev/null +++ b/common/accel-jump.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include "rawaccel-base.hpp" + +namespace rawaccel { + + struct jump_base { + static constexpr double smooth_scale = 2 * PI; + + vec2d step; + double smooth_rate; + + // requirements: args.smooth in range [0, 1] + jump_base(const accel_args& args) : + step({ args.offset, args.cap - 1 }) + { + double rate_inverse = args.smooth * step.x; + + if (rate_inverse < 1) { + smooth_rate = 0; + } + else { + smooth_rate = smooth_scale / rate_inverse; + } + } + + bool is_smooth() const + { + return smooth_rate != 0; + } + + double decay(double x) const + { + return exp(smooth_rate * (step.x - x)); + } + + double smooth(double x) const + { + return step.y / (1 + decay(x)); + } + + double smooth_antideriv(double x) const + { + return step.y * (x + log(1 + decay(x)) / smooth_rate); + } + }; + + struct jump_legacy : jump_base { + using jump_base::jump_base; + + double operator()(double x) const + { + if (is_smooth()) return smooth(x) + 1; + else if (x < step.x) return 1; + else return 1 + step.y; + } + }; + + struct jump : jump_base { + double C; + + jump(const accel_args& args) : + jump_base(args), + C(-smooth_antideriv(0)) {} + + double operator()(double x) const + { + if (x <= 0) return 1; + + if (is_smooth()) return 1 + (smooth_antideriv(x) + C) / x; + + if (x < step.x) return 1; + else return 1 + step.y * (x - step.x) / x; + } + }; + +} |