[cairo] Drawing an arrow

Bill Spitzak spitzak at gmail.com
Mon Nov 29 11:19:27 PST 2010

x0,y0 are the point you want the arrow head at. x1,y1 are a point
backwards along the line you want the arrow at (these can be the control
points for the bezier as described previously).

This makes the transformation such that 0,0 is at x0,y0 and 1,0 is 1
unit in the direction of x1,y1, and avoids unnecessary trig:

dx = x1-x0;
dy = y1-y0;
d = hypot(dx,dy); // sqrt(dx*dx+dy*dy) if you don't have hypot()
cairo_transform(cr, dx/d, dy/d, -dy/d, dx/d, x0, y0);
// I may have the 3rd and 4th args swapped here...

Now draw the arrow head pointing "left", something like this:

cairo_moveto(cr, 1,1);
cairo_lineto(cr, 0,0);
cairo_lineto(cr, 1,-1);

Further comments:

Getting the direction at interior points in the bezier is a lot harder.
The real hard part is figuring out even spacing (the 't' value does not
indicate constant spacing). There is also a desire to get arbitrary
distances along the curve, mostly so that proportional-spaced text can
follow a curve. An api to do this from the current cairo path might be
helpful, though it probably does not need to reside in cairo itself.
Cairo dash patterns have to do all this work so it may be nice to
somehow merge these.

More information about the cairo mailing list