How elliptic arc can be represented by cubic Bézier curve?
Solution 1:
http://www.spaceroots.org/documents/ellipse/ goes through the math and presents some simple equations for the control points.
Solution 2:
If anyone her is familiar with Postscript or LaTeX, I made some working examples to draw ANY elliptical, parabolic, hyperbolical and circular arc only by using a) integral (not rational) quadratic Bezier curves with the Picture environment in LaTeX and b) for the PostScript language, using integral cubic Bezier curves.
I've seen many repeated examples in the literature and on the internet, where there were attempts to do this with some magical math. This must fail from the beginning, because there is no way to produce any "good" approximation of a semicircle with only one cubic curve.
So I started to think of it from another perspective. Rational curves use weights, which are associated to the respective Bezier points to give much more control over the curve shape then integral Bezier curves. From a mathematical point of view they exactly reproduce any conic curve form (parabol, hyperbola, ellipse, circle and (degenerated) a line).
A quadratic rational Bezier curve in standard form (only the center point has a weight other then 1) converts into a integral Bezier curve, if this center weight comes close enough to 1 (the user can controll the allowed error).
Using a recursive formulation, this idea leads to a very conpact and also very precise way to replace circular arc by a series of either quadratic or cubic Bezier curves. No math is needed any more the only thing one has to provide is the error bound. If you look at Postscript itself, you'll find out that their interpreter does it the same way, Adobe calls it simply "flatness". This is exactly the same approach that I used.
If anyone here is interested in working examples (Postscript, Latex or C code), leave me a note at . I will post you back the code with many examples. In the interim, you may want to look at "Lapdf", a Latex style I published on the CTAN network. This style lets you produce pure PDF graphic from within your LaTeX document. It has all these nice things implemented, which means you can draw any conic curve by using only PDF curves, which means integral cubic curves. Another LaTeX style made by me, is the Curves style, which only uses LaTeX own internal integral quadratic Bezier curves to accomplish the same results.
If you look at the whole curve drawing/converting problem from the perspective of the rasterizing engine, which essentially brings all this to paper/screen or any other output device, you come to the conclusion that it does not matter fro the rasterizes which way the curves were produced, it only has to poduce nice aligned dots which give the impression of a smooth curve.
From my point of view (and I literally read hundrets of scientific papers on these subject) many able people waste their time, trying to overmathematize this whole area. Most of them didn't ever implement any working function/procedure to draw a perfect curve shape, but everything they ever said or wrote, can be mathematically proven. This is the great divide between theory and practice.
I'm only occasionally here to read things, so please contact me if there is really interest in solving this problem practically. For all those who can't wait, here is the C code for a routine which draws rational quadratic Bezier curves (which implies all conics), only using integral quadratic Bezier curves:
//-----------------------------------------------------------------------
// The error bound is T (0..4), which is used by delta, T = 0 gives
// extremely exact concics, but at the cost of more curve segments.
// The lin macro does linear interpolation between two coordinates.
// This is used by the function ratio(). The conic function works by
// recursively calling itself until the center weight w approaches 1.
// The conic() function need a function bezier() which draws integral
// quadratic Bezier curves. Each point is defined as (x, y, w).
//-----------------------------------------------------------------------
#define delta (pow(4, 4-T)*fabs(w-1))
#define lin(t,a,b) ((a) + (t)*((b) - (a)))
typedef float fpt[3];
// ----------------------------------------------
void ratio(float t, fpt p, fpt q, fpt r) {
r[0] = lin(t, p[0], q[0]);
r[1] = lin(t, p[1], q[1]);
r[2] = lin(t, p[2], q[2]);
}
// ----------------------------------------------
void conic(fpt *p, float w) {
float s;
fpt l[3], r[3];
if (w && delta > 1) {
s = w / (1 + w);
w = sqrt((1 + w) / 2);
ratio( 0, p[0], p[0], l[0]);
ratio( 0, p[2], p[2], r[2]);
ratio( s, l[0], p[1], l[1]);
ratio( s, r[2], p[1], r[1]);
ratio(.5, l[1], r[1], l[2]);
ratio( 0, l[2], l[2], r[0]);
conic(l, w);
conic(r, w);
}
else {
qbezier(p);
}
}
//-----------------------------------------------------------------------
At the end of this comment, I would like to mention that all of this any much more is implemented in my published versions of EiC (Ed. Breen's ANSI C-Interpreter). My version is pure batch orientated and additionally supplied with an extensive graphics library, using Nelson's high quality antialiasing.
This EiC interpreter is available for pure DOS (VESA mode, linear frame buffer), Windows (VESA mode, bank switching), Atari, Mac 68k (MPW tool), Mac OS 9 (MPW tool) and Mac OSX (using AquaTerm). I don't know anything about UNIX/Linux graphics, so this one is left out for now.
Thanks for your good website folks and keep programming.
Detlef Reimers