[Cairo] Arc support in Cairo (0.1.6)

Carl Worth cworth at east.isi.edu
Mon Sep 29 11:21:47 PDT 2003


I've just committed arc support to Cairo as of version 0.1.6. I've
done some testing and things seem to work. Let me know if you succeed
in breaking it. API feedback is also welcome, though we've been
through one round of that already some time ago[*].

The new functions are:

	void
	cairo_arc (cairo_t *cr,
		   double xc, double yc,
		   double radius,
		   double angle1, double angle2);

	void
	cairo_arc_negative (cairo_t *cr,
			    double xc, double yc,
			    double radius,
			    double angle1, double angle2);

Both functions operate by first performing an implicit "line_to" if
the current point is not the same as the initial arc point, then
appending to the current path some number of splines to approximate a
circular arc of the given radius centered at the point (xc,
yc).

All angles are measured in user space beginning from the positive X
axis and increasing toward the positive Y axis.

cairo_arc draws an arc in the direction of increasing angle, (angle2
is first incremented by 2*pi as needed until greater than angle1).
cairo_arc_negative draws an arc in the direction of decreasing angle,
(angle2 is first decremented by 2*pi as needed until less than
angle1).

The number of splines used to approximate the arc will be
automatically chosen so that the error is no greater than the current
tolerance value. For example, with the default tolerance of 0.1 device
pixels, "small" to "average" circles require 4 splines; "tiny"
circles, (radius < 5 pixels), require only 2 splines; and "large"
circles, (radius > 366 pixels), require 6 or mores splines. For those
interested in the error analysis, the comments next to the
implementation, (cairo_gstate.c), contain a more detailed description
along with pointers to the two papers that provided the original
analysis.

There are two things that are not yet implemented. First, I would like
to have one more public interface which specifies an arc with two
tangent lines and a radius:

	void
	cairo_arc_to (cairo_t *cr,
		      double x1, double y1,
		      double x2, double y2,
		      double radius);

That merely requires a conversion to the form above.

Second, Keith had a good idea which is to always draw partial-circle
arcs of the same radius using the same spline coordinates. For
example, if a 90 degree arc uses a single spline, a 45 degree arc
of the same radius would use the same spline, but draw only one half
of the spline. The idea here is to eliminate any wiggle that might be
apparent when animating a "growing" arc.

-Carl

[*] http://www.mail-archive.com/render%40xfree86.org/msg00775.html




More information about the cairo mailing list