Alastair’s Place

Software development, Cocoa, Objective-C, life. Stuff like that.

Arrows and NSBezierPath

One question that has popped-up on Apple's cocoa-dev mailing list a couple of times is how to put arrows on the ends of lines. Some operating systems have built-in support for arrows, but Cocoa and Core Graphics, in common with their PostScript and PDF roots, do not.

It is quite easy to draw a simple arrow on the end of a line or curve, by creating a triangular path and rotating it according to the orientation of the line or of the tangent to the curve (remember that the tangent to a Bézier curve at its end-point is just the line passing through the end of the curve and the adjacent control point). This looks fine for lines, but is sub-optimal for curves… which is why MetaPost, a graphics language often used with TeX, uses curved arrow heads on curves. The actual process used by MetaPost's libraries is that the end of the path is clipped using a circle, then the resulting segment is rotated either side of the original path, and the two floating ends are joined.

How can we do this with Cocoa? Well, we need some additional methods on NSBezierPath to let us chop-off a section of a particular length, but otherwise it's pretty straightforward. Take a look at [this code](/projects/ArrowDemo/), to see how it's done. The code is under a BSD-like license, so you can use it in your applications (if you want).