summaryrefslogtreecommitdiff
path: root/common/accel-jump.hpp
diff options
context:
space:
mode:
authora1xd <[email protected]>2021-09-22 20:49:04 -0400
committerGitHub <[email protected]>2021-09-22 20:49:04 -0400
commit8a4b6f57758338d5537d4671184099a4728a8cdd (patch)
treedf36529a344d5d21ff11f5ba021ec80afb4b68a4 /common/accel-jump.hpp
parentMerge pull request #87 from matthewstrasiotto/streamer_mode (diff)
parentimprove converter + docs (diff)
downloadrawaccel-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.hpp77
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;
+ }
+ };
+
+}