views:

284

answers:

6

Having searched the web, I see various people in various forums alluding to approximating a cubic curve with a quadratic one. But I can't find the formula.

What I want is this:

input: startX, startY, control1X, control1Y, control2X, control2Y, endX, endY output: startX, startY, controlX, controlY, endX, endY

Actually, since the starting and ending points will be the same, all I really need is...

input: startX, startY, control1X, control1Y, control2X, control2Y, endX, endY output: controlX, controlY

A: 

I would probably draw a series of curves instead of trying to draw one curve using a different alg. Sort of like drawing two half circles to make up a whole circle.

tcoz
A: 

In general, you'll have to use multiple quadratic curves - many cases of cubic curves can't be even vaguely approximated with a single quadratic curve.

There is a good article discussing the problem, and a number of ways to solve it, at http://www.timotheegroleau.com/Flash/articles/cubic_bezier_in_flash.htm (including interactive demonstrations).

Matthew Slattery
+2  A: 

As mentioned, going from 4 control points to 3 is normally going to be an approximation. There's only one case where it will be exact - when the cubic bezier curve is actually a degree-elevated quadratic bezier curve.

You can use the degree elevation equations to come up with an approximation. It's simple, and the results are usually pretty good.

Let's call the control points of the cubic Q0..Q3 and the control points of the quadratic P0..P2. Then for degree elevation, the equations are:

Q0 = P0
Q1 = 1/3 P0 + 2/3 P1
Q2 = 2/3 P1 + 1/3 P2
Q3 = P2

In your case you have Q0..Q3 and you're solving for P0..P2. There are two ways to compute P1 from the equations above:

P1 = 3/2 Q1 - 1/2 Q0
P1 = 3/2 Q2 - 1/2 Q3

If this is a degree-elevated cubic, then both equations will give the same answer for P1. Since it's likely not, your best bet is to average them. So,

P1 = -1/4 Q0 + 3/4 Q1 + 3/4 Q2 - 1/4 Q3

To translate to your terms:

controlX = -0.25*startX + .75*control1X + .75*control2X -0.25*endX

Y is computed similarly - the dimensions are independent, so this works for 3d (or n-d).

This will be an approximation. If you need a better approximation, one way to get it is by subdividing the initial cubic using the deCastlejau algorithm, and then degree-reduce each segment. If you need better continuity, there are other approximation methods that are less quick and dirty.

tfinniga
+1. Can you suggest a reference for Bezier curves please ?
Denis
The main reference I use is from a CAGD class I took: http://tom.cs.byu.edu/~557/text/ Chapter 2 covers Bezier curves.
tfinniga
A: 

Another derivation of tfinniga's answer:
First see Wikipedia Bezier curve for the formulas for quadratic and cubic Bezier curves (also nice animations):

Q(t) = (1-t)^2 P0 + 2 (1-t) t Q + t^2 P3
P(t) + (1-t)^3 P0 + 3 (1-t)^2 t P1 + 3 (1-t) t^2 P2 + t^3 P3

Require these to match at the middle, t = 1/2:

(P0 + 2 Q + P3) / 4 = (P0 + 3 P1 + 3 P2 + P3) / 8  
=> Q = P1 + P2 - (P0 + P1 + P2 + P3) / 4  

(Q written like this has a geometric interpretation:

Pmid = middle of P0 P1 P2 P3  
P12mid = midway between P1 and P2  
draw a line from Pmid to P12mid, and that far again: you're at Q.  

Hope this makes sense -- draw a couple of examples.)

Denis
A: 

Try looking for opensource Postcript font to Truetype font converters. I'm sure they have it. Postscript uses cubic bezier curves, whereas Truetype uses quadratic bezier curves. Good luck.

cottondave1
A: 

Conventions/terminology

  • Cubic defined by: P1/2 - anchor points, C1/C2 control points
  • |x| is the euclidean norm of x
  • mid-point approx of cubic: a quad that shares the same anchors with the cubic and has the control point at C = (3·C2 - P2 + 3·C1 - P1)/4

Algorithm

  1. pick an absolute precision (prec)
  2. Compute the Tdiv as the root of (cubic) equation sqrt(3)/18 · |P2 - 3·C2 + 3·C1 - P1|/2 · Tdiv ^ 3 = prec
  3. if Tdiv < 0.5 divide the cubic at Tdiv. First segment [0..Tdiv] can be approximated with by a quadratic, with a defect less than prec, by the mid-point approximation. Repeat from step 2 with the second resulted segment (corresponding to 1-Tdiv)
  4. 0.5<=Tdiv<1 - simply divide the cubic in two. The two halves can be approximated by the mid-point approximation
  5. Tdiv>=1 - the entire cubic can be approximated by the mid-point approximation

The "magic formula" at step 2 is demonstrated (with interactive examples) on this page.

Adrian