[cairo] Pen vertex estimation

Keith Packard keithp at keithp.com
Fri Oct 1 10:28:40 PDT 2004


In constructing pens, the hardest part is estimating the number of 
vertices needed to satisfy the tolerance.

Under the transformation matrix, the circular user-space pen will be
transformed to some ellipse; given the pixel-dimension of the major axis of
that ellipse, it's straightforward to compute the number of vertices 
needed to construct a polygon within the specified tolerance.

So, the hard piece of problem actually devolves to a computation of the 
major axis length of an ellipse given the transformation matrix.

The current code computes the determinant of the matrix, which represents 
the area expansion factor for the matrix.  Assuming that the matrix scales 
in only one direction, this expansion factor will also represent the 
scaling of the major axis dimension.  We don't exactly restrict matrices 
to this form though.  

For matrices scaling the same amount in both directions, this equation over
computes the major axis length by an exponent of two, which is a waste of
CPU.  For matrices which scale up in one direction and down in another,
this can actually *under* estimate the number of vertices needed by an 
arbitrary amount.

So, we clearly need a different function.

Consider our user-space pen as a circle of radius 1 with a square
circumscribing it.  Under the transformation, the circle becomes an ellipse
and the square a parallelogram.  Because the transform is affine, the
circle remains inscribed within the square.  Hence, the major axis must
therefore be less than the distance from the origin to the furthest corner
of the parallelogram.  Again using the fact that the transform is affine, that
furthest is either the transformation of the point [1,1] or [-1,1] (or 
their mirrors through the origin)

Given the matrix

	| a b |
 	| c d |

[1,1]	-> [a + c, b + d]
[-1,1]	-> [-a + c, -b + d]
[1,-1]	-> [a - c, b - d]
[-1,-1]	-> [-a - c, -b - d]

The maximum over all four values is [|a| + |b|, |c| + |d|].

The distance from the origin to this point represents a bound on the major 
axis length for the ellipse.  We can either compute this exactly, or use 
the manhatten distance as an approximation, in which case our ellipse is 
bounded by |a| + |b| + |c| + |d|.  I'm using the latter for twin where the 
sqrt operation is expensive.

-keith


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20041001/b06cae35/attachment.pgp


More information about the cairo mailing list