[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 


More information about the cairo mailing list