[cairo] cairo_arc Versus cairo_arc_negative

Lawrence D'Oliveiro ldo at geek-central.gen.nz
Sun Sep 18 00:03:43 UTC 2016


One of the changes I made in Qahirah compared to the underlying C API
was to combine “cairo_arc” and “cairo_arc_negative” into a single
“Context.arc” method, with an additional “negative” argument that tells
it which way round the arc should go.

Initially, this was done more on a whim than anything else. But I think
it turns out it was a good idea. For example, look at my code for
computing a fillet
<https://github.com/ldo/qahirah_examples/blob/master/fillet>--rounding
off a corner with a circular arc. Given the lines (p0, p1) and (p1, p2)
meeting at p1, the direction angles of the lines are computed easily
enough:

    dirn1 = (p0 - p1).angle()
    dirn2 = (p2 - p1).angle()

But the bisecting direction is a little tricky:

    mid_dirn = (dirn1 + dirn2) / 2

Because if the angle between the line directions is greater than π
(180°)

    flip = abs(dirn2 - dirn1) > math.pi

then the bisecting direction needs to go the opposite way.

The direction of the arc depends on the ordering of the two
line directions, and also on flip:

    clockwise = (dirn2 > dirn1) == flip

So, after some additional calculation I won’t bother repeating here, the
fillet arc is constructed quite conveniently as follows:

    g.arc \
      (
        centre = fillet_centre,
        radius = r,
        angle1 = (t1 - fillet_centre).angle(),
        angle2 = (t2 - fillet_centre).angle(),
        negative = not clockwise
      )

So it is done with a single graphics API call, rather than having to
choose between two calls depending on the “clockwise” flag; Qahirah
itself makes the choice, the caller doesn’t have to worry about it.


More information about the cairo mailing list