From 7361457ed17670b37279f12fe334e7a9ce7ea34e Mon Sep 17 00:00:00 2001 From: Jacob Palecki Date: Thu, 16 Sep 2021 01:29:51 -0700 Subject: Get power cap working --- common/accel-power.hpp | 122 +++++++++++++++++++++++++++-- grapher/Models/Options/AccelTypeOptions.cs | 2 +- 2 files changed, 115 insertions(+), 9 deletions(-) diff --git a/common/accel-power.hpp b/common/accel-power.hpp index b3e16fb..0b9353d 100644 --- a/common/accel-power.hpp +++ b/common/accel-power.hpp @@ -7,10 +7,10 @@ namespace rawaccel { struct power_base { - static double base_fn(double x, const accel_args& args) + static double base_fn(double x, double scale, const accel_args& args) { // f(x) = w(mx)^k - return args.weight * pow(args.scale * x, args.exponent_power); + return args.weight * pow(scale * x, args.exponent_power); } }; @@ -18,51 +18,157 @@ namespace rawaccel { template <> struct power : power_base { - vec2d cap = { DBL_MAX, DBL_MAX }; + double cap = DBL_MAX; + double scale = 0; power(const accel_args& args) { + // Note that cap types may overwrite this below. + scale = args.scale; + + switch (args.cap_mode){ + case classic_cap_mode::in: + if (args.cap.x > 0) + { + cap = base_fn( + args.cap.x, + args.scale, + args); + } + break; + case classic_cap_mode::io: + if (args.cap.x > 0 && + args.cap.y > 1) + { + cap = args.cap.y; + scale = scale_from_sens_point( + args.cap.y, + args.cap.x, + args.exponent_power); + } + break; + case classic_cap_mode::out: + default: + if (args.cap.y > 1) + { + cap = args.cap.y; + } + break; + } + /* if (args.cap.x > 0) { cap.x = args.cap.x; cap.y = base_fn(cap.x, args); } + */ } double operator()(double speed, const accel_args& args) const { - if (speed < cap.x) { - return base_fn(speed, args); - } - return cap.y; + return minsd(base_fn(speed, scale, args), cap); } + double static scale_from_sens_point(double sens, double input, double power) + { + return pow(sens, 1 / power) / input; + } }; template <> struct power : power_base { vec2d cap = { DBL_MAX, DBL_MAX }; double constant = 0; + double scale = 0; power(const accel_args& args) { + /* if (args.cap.x > 0) { cap.x = args.cap.x; double output = base_fn(cap.x, args); cap.y = output * (args.exponent_power + 1); constant = -args.exponent_power * output * args.cap.x; } + */ + + // Note that cap types may overwrite this below. + scale = args.scale; + + switch (args.cap_mode) { + case classic_cap_mode::in: + if (args.cap.x > 0) { + cap.x = args.cap.x; + cap.y = gain( + args.cap.x, + args.exponent_power, + scale); + + constant = integration_constant( + cap.x, + cap.y, + base_fn(cap.x, scale, args)); + } + case classic_cap_mode::io: + if (args.cap.x > 0 && + args.cap.y > 1) { + cap.x = args.cap.x; + cap.y = args.cap.y; + scale = scale_from_gain_point( + args.cap.x, + args.cap.y, + args.exponent_power); + + constant = integration_constant( + cap.x, + cap.y, + base_fn(cap.x, scale, args)); + } + case classic_cap_mode::out: + default: + if (args.cap.y > 1) { + cap.y = args.cap.y; + cap.x = gain_inverse( + args.cap.y, + args.exponent_power, + scale); + + constant = integration_constant( + cap.x, + cap.y, + base_fn(cap.x, scale, args)); + } + break; + } } double operator()(double speed, const accel_args& args) const { if (speed < cap.x) { - return base_fn(speed, args); + return base_fn(speed, scale, args); } else { return cap.y + constant / speed; } } + double static gain_inverse(double gain, double power, double scale) + { + return pow(gain / (power + 1), 1 / power) / scale; + } + double static gain(double input, double power, double scale) + { + return (power + 1) * pow(input * scale, power); + } + + double static scale_from_gain_point(double input, double gain, double power) + { + return pow(gain / (power + 1), 1 / power) / input; + } + + double static integration_constant(double input, double gain, double output) + { + return (output - gain) * input; + } }; } diff --git a/grapher/Models/Options/AccelTypeOptions.cs b/grapher/Models/Options/AccelTypeOptions.cs index 3d2f840..b7a7b7b 100644 --- a/grapher/Models/Options/AccelTypeOptions.cs +++ b/grapher/Models/Options/AccelTypeOptions.cs @@ -323,7 +323,7 @@ namespace grapher } if (PowerCap.Visible) { - args.scale = ClassicCap.Slope.Field.Data; + args.scale = PowerCap.Slope.Field.Data; args.cap.x = PowerCap.In.Field.Data; args.cap.y = PowerCap.Out.Field.Data; args.capMode = PowerCap.CapTypeOptions.GetSelectedCapMode(); -- cgit v1.2.3