Bezier interpolation between two points
| 42 | |
| 43 | // Bezier interpolation between two points |
| 44 | double InterpolateBezierCurve(Point const & left, Point const & right, double const target, double const allowed_error) { |
| 45 | double const X_diff = right.co.X - left.co.X; |
| 46 | double const Y_diff = right.co.Y - left.co.Y; |
| 47 | Coordinate const p0 = left.co; |
| 48 | Coordinate const p1 = Coordinate(p0.X + left.handle_right.X * X_diff, p0.Y + left.handle_right.Y * Y_diff); |
| 49 | Coordinate const p2 = Coordinate(p0.X + right.handle_left.X * X_diff, p0.Y + right.handle_left.Y * Y_diff); |
| 50 | Coordinate const p3 = right.co; |
| 51 | |
| 52 | double t = 0.5; |
| 53 | double t_step = 0.25; |
| 54 | do { |
| 55 | // Bernstein polynoms |
| 56 | double B[4] = {1, 3, 3, 1}; |
| 57 | double oneMinTExp = 1; |
| 58 | double tExp = 1; |
| 59 | for (int i = 0; i < 4; ++i, tExp *= t) { |
| 60 | B[i] *= tExp; |
| 61 | } |
| 62 | for (int i = 0; i < 4; ++i, oneMinTExp *= 1 - t) { |
| 63 | B[4 - i - 1] *= oneMinTExp; |
| 64 | } |
| 65 | double const x = p0.X * B[0] + p1.X * B[1] + p2.X * B[2] + p3.X * B[3]; |
| 66 | double const y = p0.Y * B[0] + p1.Y * B[1] + p2.Y * B[2] + p3.Y * B[3]; |
| 67 | if (fabs(target - x) < allowed_error) { |
| 68 | return y; |
| 69 | } |
| 70 | if (x > target) { |
| 71 | t -= t_step; |
| 72 | } |
| 73 | else { |
| 74 | t += t_step; |
| 75 | } |
| 76 | t_step /= 2; |
| 77 | } while (true); |
| 78 | } |
| 79 | // Interpolate two points using the right Point's interpolation method |
| 80 | double InterpolateBetween(Point const & left, Point const & right, double target, double allowed_error) { |
| 81 | // check if target is outside of the extremities poits |
no test coverage detected