@@ -42,7 +42,10 @@ MeasureAxis::MeasureAxis(Math::Range<double> interval,
4242 unit (std::string{unit}),
4343 origMeasureName (std::string{measName}),
4444 step (step ? *step : Math::Renard::R5().ceil(range.size() / 5.0 ))
45- {}
45+ {
46+ if (std::signbit (this ->step ->value ) != std::signbit (range.size ()))
47+ this ->step ->value *= -1 ;
48+ }
4649
4750bool MeasureAxis::operator ==(const MeasureAxis &other) const
4851{
@@ -68,8 +71,53 @@ MeasureAxis interpolate(const MeasureAxis &op0,
6871 interpolate (op0.origMeasureName , op1.origMeasureName , factor);
6972
7073 if (op0.enabled .get () && op1.enabled .get ()) {
71- res.range = Math::interpolate (op0.range , op1.range , factor);
72- res.step = interpolate (op0.step , op1.step , factor);
74+ constexpr auto MAX = std::numeric_limits<double >::max () / 2 ;
75+ using Math::Floating::is_zero;
76+
77+ const auto s0 = op0.range .size ();
78+ const auto s1 = op1.range .size ();
79+
80+ const auto s0Inv = is_zero (s0) ? MAX : 1 / s0;
81+ const auto s1Inv = is_zero (s1) ? MAX : 1 / s1;
82+
83+ const auto interp = Math::interpolate (s0Inv, s1Inv, factor);
84+
85+ const auto s = is_zero (interp) ? MAX : 1 / interp;
86+
87+ res.range = Math::Range<double >::Raw (
88+ Math::interpolate (op0.range .getMin () * s0Inv,
89+ op1.range .getMin () * s1Inv,
90+ factor)
91+ * s,
92+ Math::interpolate (op0.range .getMax () * s0Inv,
93+ op1.range .getMax () * s1Inv,
94+ factor)
95+ * s);
96+
97+ auto step = Math::interpolate (op0.step .get () * s0Inv,
98+ op1.step .get () * s1Inv,
99+ factor)
100+ * s;
101+
102+ if (auto op0sign = std::signbit (op0.step .get ());
103+ op0sign == std::signbit (op1.step .get ()))
104+ res.step = interpolate (op0.step ,
105+ op1.step ,
106+ Math::Range<double >::Raw (op0.step .get (),
107+ op1.step .get ())
108+ .rescale (step));
109+ else if (auto max = std::copysign (MAX, step);
110+ op0sign == std::signbit (step))
111+ res.step = interpolate (op0.step ,
112+ Anim::Interpolated{max},
113+ Math::Range<double >::Raw (op0.step .get (), max)
114+ .rescale (step));
115+ else
116+ res.step = interpolate (op1.step ,
117+ Anim::Interpolated{max},
118+ Math::Range<double >::Raw (op1.step .get (), max)
119+ .rescale (step));
120+
73121 res.unit = interpolate (op0.unit , op1.unit , factor);
74122 }
75123 else if (op0.enabled .get ()) {
0 commit comments