[Math] How to approximate/connect two continuous cubic Bézier curves with/to a single one

approximationbezier-curve

I subdivide a cubic Bézier curve at a given t value using de Casteljau’s algorithm, which yields two cubic Bézier curves. Afterwards I “scale” the second curve (proportionally).

I’d like to reconnect or approximate the two curves to/with a single curve in a third step. Is that possible?

two connected Bézier curves

This illustrates what I’m intending to do.

I guess reversing de Casteljau’s algorithm won’t work because I don’t have one of the intermediate points.

If there are multiple approaches, I’d favor a simpler (faster to compute) strategy.

Thanks in advance.

Update:
Maybe this figure makes it more clear; it shows all the points I have:
Bézier curves with convex hulls

The original cubic Bézier curve is defined by the points $ p_{0}, p_{1}, p_{2}, p_{3} $.

It is divided at a given $ t $ (timing) value using de Casteljau’s algorithm, which yields the points $ q_{1}, r_{2}, i_{1}, q_{2}, r_{1}, k $ where $ k $ is the division point.

The two subcurves are defined by the control points $ p_{0}, q_{1}, q_{2}, k $ and $ k, r_{1}, r_{2}, p_{3} $, respectively.

The scaled second subcurve is defined by the points $ k, {r}' _{1}, {r}' _{2}, {r}' _{3} $

Scaling is applied as follows: $ {p}' = k + (p – k) \cdot factor $ for $ r_{1}, r_{2}, p_{3} $

Best Answer

You probably already know this, but let me explicitly point out:

== exact match ==

It is not possible to construct a single cubic Bezier curve that exactly matches your new curve.

A single cubic Bezier curve has a constant "curvature" A along its length. When you shrink it, the new curve has "sharper" curvature B (but still constant along the length of the new curve).

It is not possible to construct a single cubic Bezier curve -- since, like all single cubic curves, it has constant curvature C along its length -- such that C=A along the part of the length, and C=B along the rest of the length, where A<>B.

(I'm mis-using the term "curvature" here for something that is more precisely the 3rd derivative of a curve, sometimes called the "jerk").

== approximation ==

Perhaps the simplest approximation is: Use the initial starting point and first control knot -- p0 and p1, and the final control knot and final ending point -- r'2 and r'3. Use those 4 points as the start, control knots, and endpoint of a Bezier curve that approximates the one you want: a0, a1, a2, a3.

This approximation exactly hits the endpoints of your desired curve, and has the same initial and final slope at those endpoints, but it slightly diverges from your desired curve in the middle. In particular, it probably doesn't go exactly through the cutpoint K.

There are many other possible approximations you could make. The "Don Lancaster's Guru's Lair Cubic Spline Library" may have the details I'm leaving out:

  • It is possible to nudge a1 along the line p0-p1, or to nudge a2 along the line r'2-r'3 -- or both -- such that the approximation curve not only starts and ends at the same points and slopes, but also passes through the cutpoint K.
  • pick any 4 points along your new curve (perhaps the endpoints, the cutpoint K, and some other point) and generate a cubic Bezier curve that goes exactly through all 4 points.
  • pick many points along your new curve -- bunched together in places where curve matching is important, perhaps near the endpoints and point K, and spaced further apart where curve matching is not so important -- and generate a cubic Bezier curve that is a least-squares best fit to those points.