@@ -40,7 +40,14 @@ namespace {
4040 return p.co .X < x;
4141 }
4242
43- double InterpolateBezierCurve (Point const & left, Point const & right, bool const needY, double const target, double const allowed_error) {
43+ double InterpolateLinearCurve (Point const & left, Point const & right, double const target) {
44+ double const diff_Y = right.co .Y - left.co .Y ;
45+ double const diff_X = right.co .X - left.co .X ;
46+ double const slope = diff_Y / diff_X;
47+ return left.co .Y + slope * (target - left.co .X );
48+ }
49+
50+ double InterpolateBezierCurve (Point const & left, Point const & right, double const target, double const allowed_error) {
4451 double const X_diff = right.co .X - left.co .X ;
4552 double const Y_diff = right.co .Y - left.co .Y ;
4653 Coordinate const p0 = left.co ;
@@ -63,12 +70,10 @@ namespace {
6370 }
6471 double const x = p0.X * B[0 ] + p1.X * B[1 ] + p2.X * B[2 ] + p3.X * B[3 ];
6572 double const y = p0.Y * B[0 ] + p1.Y * B[1 ] + p2.Y * B[2 ] + p3.Y * B[3 ];
66- bool const stop = abs (target - (needY ? x : y)) < allowed_error;
67- bool const move_left = (needY ? x : y) > target;
68- if (stop) {
69- return needY ? y : x;
73+ if (abs (target - x) < allowed_error) {
74+ return y;
7075 }
71- if (move_left ) {
76+ if (x > target ) {
7277 t -= t_step;
7378 }
7479 else {
@@ -77,6 +82,17 @@ namespace {
7782 t_step /= 2 ;
7883 } while (true );
7984 }
85+
86+
87+ double InterpolateBetween (Point const & left, Point const & right, double target, double allowed_error) {
88+ assert (left.co .X < target);
89+ assert (target <= right.co .X );
90+ switch (right.interpolation ) {
91+ case CONSTANT: return left.co .Y ;
92+ case LINEAR: return InterpolateLinearCurve (left, right, target);
93+ case BEZIER: return InterpolateBezierCurve (left, right, target, allowed_error);
94+ }
95+ }
8096}
8197
8298
@@ -245,25 +261,7 @@ double Keyframe::GetValue(int64_t index) const {
245261 return candidate->co .Y ;
246262 }
247263 std::vector<Point>::const_iterator predecessor = candidate - 1 ;
248- assert (predecessor->co .X < index);
249- assert (index < candidate->co .X );
250-
251- // CONSTANT and LINEAR interpolations are fast to compute!
252- switch (candidate->interpolation ) {
253- case CONSTANT: return predecessor->co .Y ;
254- case LINEAR: {
255- double const diff_Y = candidate->co .Y - predecessor->co .Y ;
256- double const diff_X = candidate->co .X - predecessor->co .X ;
257- double const slope = diff_Y / diff_X;
258- return predecessor->co .Y + slope * (index - predecessor->co .X );
259- }
260- case BEZIER: break ;
261- }
262-
263- // BEZIER curve!
264- assert (candidate->interpolation == BEZIER);
265-
266- return InterpolateBezierCurve (*predecessor, *candidate, true , index, 0.01 );
264+ return InterpolateBetween (*predecessor, *candidate, index, 0.01 );
267265}
268266
269267// Get the rounded INT value at a specific index
0 commit comments