[cairo] Re: adding a new curve type to cairo

Carl Worth cworth at cworth.org
Thu Jul 13 18:15:30 PDT 2006


On Thu, 13 Jul 2006 12:49:42 -0700 (PDT), Jeff Smith wrote:
> --- Jeff Smith <whydoubt at yahoo.com> wrote:
> > --- Niki Spahiev <niki.spahiev at gmail.com> wrote:
> > > Carl Worth wrote:
> > > > poorly approximated with individual cubic B�ziers, (even the common
> > > > approach of 4 cubic B�ziers per circle is poor, so cairo_arc does
> > > > better than that when necessary).
> > > 
> > > Any info on how poor it is?
> > 
> > http://cgafaq.info/wiki/Bezier_Circle.  I am pretty sure the formula is correct, as I
> > calculated it independently once upon a time.  The accuracy stated I cannot vouch for.
> 
> I found a program I wrote once to calculate the accuracy.  I calculated it with higher
> precision than that given on the page I just cited.  The most inaccurate point is off by
> 0.027253% of the radius.  This occurs at +/-19.02 degrees from each of (0, 90, 180, 270)
> degrees. 

The papers cited there are the same papers I read when doing the
implementation in cairo. Here are the comments I wrote in cairo-arc.c
when I did that:

/* We want to draw a single spline approximating a circular arc radius
   R from angle A to angle B. Since we want a symmetric spline that
   matches the endpoints of the arc in position and slope, we know
   that the spline control points must be:

	(R * cos(A), R * sin(A))
	(R * cos(A) - h * sin(A), R * sin(A) + h * cos (A))
	(R * cos(B) + h * sin(B), R * sin(B) - h * cos (B))
	(R * cos(B), R * sin(B))

   for some value of h.

   "Approximation of circular arcs by cubic poynomials", Michael
   Goldapp, Computer Aided Geometric Design 8 (1991) 227-238, provides
   various values of h along with error analysis for each.

   From that paper, a very practical value of h is:

	h = 4/3 * tan(angle/4)

   This value does not give the spline with minimal error, but it does
   provide a very good approximation, (6th-order convergence), and the
   error expression is quite simple, (see the comment for
   _arc_error_normalized).
*/

/* Spline deviation from the circle in radius would be given by:

	error = sqrt (x**2 + y**2) - 1

   A simpler error function to work with is:

	e = x**2 + y**2 - 1

   From "Good approximation of circles by curvature-continuous Bezier
   curves", Tor Dokken and Morten Daehlen, Computer Aided Geometric
   Design 8 (1990) 22-41, we learn:

	abs (max(e)) = 4/27 * sin**6(angle/4) / cos**2(angle/4)

   and
	abs (error) =~ 1/2 * e

   Of course, this error value applies only for the particular spline
   approximation that is used in _cairo_gstate_arc_segment.
*/

You can find the current version of cairo-arc.c here:

http://gitweb.freedesktop.org/?p=cairo;a=blob;h=fdef6a32570aa4d6df8aad10f780b57659acec12;hb=6a5d66f651b7fe94e74ee803a452bac5b54c95ca;f=src/cairo-arc.c

The error calculation above suggests that the error for using 4
splines for a circle would be about:

	radius * 1/2 * 4/27 * sin**6(pi/8) / cos**2(pi/8)

which is about:

	radius * 0.00027256714373

Which says that we're all pretty much in agreement about the error.

So, if you only care about getting within the nearest pixel, using 4
splines per circle is pretty good and the error won't exceed 0.5
pixels until a radius greater than about 1834 or so.

Meanwhile, cairo will use enough splines to maintain an accuracy
within the tolerance value specified by cairo_set_tolerance, (which is
0.1 pixels by default). So, by default cairo is using more than 4
splines per circle at radius values greater than about 367.

And, interestingly enough, cairo will also use only 2 splines per
circle when it can get away with it. The error for approximating an
angle of pi instead of pi/2 gets bad pretty fast, roughly:

	radius * 1/2 * 4/27 * sin**6(pi/4) / cos**2(pi/4)

which is about:

	radius * 0.018518518518518

But even with the default tolerance of 0.1 pixels, this means that 2
splines per pixel is sufficient for circles of radius 5 or less. That
was a surprising result to me. And I've wondered if many other systems
actually take advantage of that.

-Carl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20060713/4310efc8/attachment.pgp


More information about the cairo mailing list