diff --git a/core/divelist.cpp b/core/divelist.cpp index 9b3ebf4f3..d198800fc 100644 --- a/core/divelist.cpp +++ b/core/divelist.cpp @@ -432,7 +432,7 @@ static void add_dive_to_deco(struct deco_state *ds, const struct dive &dive, boo int j; for (j = t0; j < t1; j++) { - depth_t depth = { .mm = interpolate(psample.depth.mm, sample.depth.mm, j - t0, t1 - t0) }; + depth_t depth = interpolate(psample.depth, sample.depth, j - t0, t1 - t0); auto gasmix = loop.at(j).first; add_segment(ds, dive.depth_to_bar(depth), gasmix, 1, sample.setpoint.mbar, loop_d.at(j), dive.sac, diff --git a/core/planner.cpp b/core/planner.cpp index 7489c8c35..69be37dbf 100644 --- a/core/planner.cpp +++ b/core/planner.cpp @@ -104,7 +104,7 @@ static void interpolate_transition(struct deco_state *ds, struct dive *dive, dur int32_t j; for (j = t0.seconds; j < t1.seconds; j++) { - depth_t depth = depth_t { .mm = interpolate(d0.mm, d1.mm, j - t0.seconds, t1.seconds - t0.seconds) }; + depth_t depth = interpolate(d0, d1, j - t0.seconds, t1.seconds - t0.seconds); add_segment(ds, dive->depth_to_bar(depth), gasmix, 1, po2.mbar, divemode, prefs.bottomsac, true); } if (d1.mm > d0.mm) diff --git a/core/profile.cpp b/core/profile.cpp index bd14ac536..7a85dd660 100644 --- a/core/profile.cpp +++ b/core/profile.cpp @@ -876,6 +876,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_ int time_stepsize = 20; depth_t max_ceiling; depth_t depth { .mm = entry.depth }; + depth_t prev_depth { .mm = prev.depth }; divemode_t current_divemode = loop_d.at(entry.sec); struct gasmix gasmix = loop.at(t1).first; @@ -888,7 +889,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_ if (t0 != t1 && t1 - t0 < time_stepsize) time_stepsize = t1 - t0; for (int j = t0 + time_stepsize; j <= t1; j += time_stepsize) { - depth_t new_depth { .mm = interpolate(prev.depth, depth.mm, j - t0, t1 - t0) }; + depth_t new_depth = interpolate(prev_depth, depth, j - t0, t1 - t0); add_segment(ds, dive->depth_to_bar(new_depth), gasmix, time_stepsize, entry.o2pressure.mbar, current_divemode, entry.sac, in_planner); entry.icd_warning = ds->icd_warning; @@ -915,7 +916,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_ /* If using VPM-B, take first_ceiling_pressure as the deepest ceiling */ if (decoMode(in_planner) == VPMB) { if (current_ceiling.mm >= first_ceiling.mm || - (time_deep_ceiling == t0 && depth.mm == prev.depth)) { + (time_deep_ceiling == t0 && depth.mm == prev_depth.mm)) { time_deep_ceiling = t1; first_ceiling = current_ceiling; ds->first_ceiling_pressure.mbar = dive->depth_to_mbar(first_ceiling); diff --git a/core/units.h b/core/units.h index 0515076df..dc32322d7 100644 --- a/core/units.h +++ b/core/units.h @@ -2,6 +2,8 @@ #ifndef UNITS_H #define UNITS_H +#include "interpolate.h" + #include #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -86,6 +88,12 @@ * _permille -> fraction_t in ‰ * _percent -> fraction_t in % * + * For now, addition and subtraction of values of the same type + * are supported. + * + * A free standing interpolate() function can be used to interpolate + * between types of the same kind (see also the interpolate.h header). + * * We don't actually use these all yet, so maybe they'll change, but * I made a number of types as guidelines. */ @@ -140,6 +148,15 @@ struct unit_base { } }; +template ::value, bool> = true> +T interpolate(T a, T b, int part, int whole) +{ + return T::from_base( + interpolate(a.get_base(), b.get_base(), part, whole) + ); +} + struct duration_t : public unit_base { int32_t seconds = 0; // durations up to 34 yrs