# [cairo] Derivation of the mitre limit

Carl Worth cworth at cworth.org
Mon Oct 29 14:44:15 PDT 2007

```On Wed, 3 Oct 2007 21:09:02 +0100, Chris Wilson wrote:
> The original bug is a little more worrisome as the cairo_arc() generates
> a pair of curves whose endpoints are nearly parallel but very slightly
> displaced. As the lines are nearly parallel, they pass the mitre limit
> check when in fact they generate an ugly mitre - which although added to
> the traps is not drawn, but still affects the extents.

Hi Chris,

Somehow I totally missed this email from you, (until now when I've
gone and duplicated some of the same detective work). Anyway, I really
want to get this bug fixed, so here are some unsorted comments and
questions:

* Why isn't the giant miter trapezoid getting drawn at all?

* We're dealing with the join of two splines here that result from the
decomposition of an arc. By definition, that result is smooth enough
without needing any join. And even if we did want a join, we would
want a round join here, definitely not a miter join.

Now, our current implementation doesn't pass along enough data to
"know" that at this point. But might it be worth rewriting things so
that it does?

> -    if (in->cw.x == out->cw.x
> +    if ((in->cw.x == out->cw.x
>  	&& in->cw.y == out->cw.y
>  	&& in->ccw.x == out->ccw.x
>  	&& in->ccw.y == out->ccw.y)
> +	|| (_PointDistanceSquaredToPoint (&in->cw, &out->cw) < tolerance_sqr &&
> +	    _PointDistanceSquaredToPoint (&in->ccw, &out->ccw) < tolerance_sqr))

* At first this seems wrong to me. If there's supposed to be a miter
join, then what one might want to compute is a bound on the error of
using a bevel rather than a miter join and compare *that* to the
tolerance. But you're right that if the tolerance allows these two
points to be considered coincident then its legitimate to treat them
that way.

Though I still might prefer it to actually use a bevel join instead
of no join at all. If we accept an error of at most 'tolerance' do
we also accept an error that is a triangular area of arbitrary size
that measures no larger than 'tolerance' across one particular axis?
I don't think so.

* I do understand that the bug is coming from computing the
intersection of two lines that are arbitrarily close to parallel,
(just one sub-pixel position off in both X and Y when measured
across the length of an entire linear segment). And the two lines
are also positioned only one sub-pixel apart from each other, (which
effectively means that the separation of these two points is in a
random direction rather than a direction relating to the slope).

But I still haven't come up with a test for preventing the bug. It
seems like we need a "convert miter to bevel" test at the opposite
extreme of the existing test. The current test says, "if the angular
change in the slopes is too great" then convert to a bevel. But here
we want to convert to a bevel because the angular change is so
small.

I guess I'm still puzzling over what cases might remain buggy even
with the "points are separated by a distance less than the
tolerance" test.

Thanks again for working on this tricky case, (and thanks very much
for introducing a FAIL test that forced me to look closer at it).

-Carl

PS. If anyone else wants to similarly force me to do some work,
introducing a test that fails with the image backend is demonstrably a
good way to do it.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.cairographics.org/archives/cairo/attachments/20071029/abcb222d/attachment.pgp
```