# [cairo] Drawing an arrow

Dov Grobgeld dov.grobgeld at gmail.com
Wed Nov 24 03:39:32 PST 2010

```Things get even more complex if you want the arrow head to bend with the
curvature of the path. The only package I know that can do that is MetaPost.
See page 42 of:

http://tug.org/docs/metapost/mpman.pdf

Imho, the source code of MetaFont and MetaPost are great resources for the
math involved.

Regards,
Dov

On Wed, Nov 24, 2010 at 12:48, Angus Johnson <angus at internode.on.net> wrote:

> On 24/11/2010 8:50 PM, donn wrote:
>
>> On 23/11/2010 19:09, Stefan Salewski wrote:
>>
>>> Can you imagine building an arrow of 3 or more line segments?
>>>
>> The OP is a question I would like to see answered too. The problem is how
>> to find the three points to define the arrow. If you have a bezier-curve, so
>> the line is some S shape, how do you get the arrow to point along the
>> direction that the curve sort of ends in?
>>
>
> This isn't a simple task. What I do in another library is ...
> 1. flatten the curve (into a series of straight edges)
> 2. given a specified distance between arrow tip and arrow base,
>    shorten the curve by that distance (removing some segments and/or
> shortening the last)
> 3. get the angle 'a' between the original end and the new end. (I don't
> recommend using the angle of the very last straight segment, or the control
> point, because if the bezier is very curved near the end the arrow base will
> be no where near where the adjusted line starts.)
> 4. use the perpendicular of 'a' and a specified distance from the base to
> locate arrow 'wings' points.
>
> Also, I suggest it'd be very helpful to have a couple of basic arrow
> drawing routines in the library - that returns coords for 3 pointed and 4
> pointed arrows of a specified size (ie between tip and base).
> eg typedef cairo_path_end_type enum {CAIRO_END_TYPE_START,
> CAIRO_END_TYPE_END, CAIRO_END_TYPE_BOTH} cairo_path_end_type_t;
> cairo_path_t*  cairo_get_3pt_arrow_coords_for_path(cairo_t *cr, double
> size, cairo_path_end_type_t ends);
>
> They could be combined with the following couple of functions ...
> 1. cairo_bool_t cairo_get_point_at_dist_from_path_end(cairo_t *cr, double
> dist, cairo_path_end_type_t end, double *x, double *y);
> 2. cairo_bool_t cairo_shorten_path(cairo_t *cr, double dist,
> cairo_path_end_type_t ends);
>
> --
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20101124/465e04a9/attachment.html>
```