[cairo] Path_extents after coordinate system is rotated.
Uli Schlachter
psychon at znc.in
Sat Apr 11 00:05:16 PDT 2015
Am 11.04.2015 um 04:43 schrieb Lawrence D'Oliveiro:
> On Wed, 08 Apr 2015 15:05:31 +0200, Stefan Salewski wrote:
>
>> Seems that new path_extents() after rotation is not
>> calculated from path itself, but from initial path_extents().
>
> Ah, but what happens if you, say, rotate the coordinate system before
> constructing the path, and leave it rotated while asking for the
> path_extents?
[...]
The user -> surface coordinate transformation matrix is applied while the path
is constructed. So when you rotate by 90° and move to point (0, 1), cairo
internally records a move to (1, 0). Thanks to this, later transformations do
not influence earlier path operations. The user coordinate system only exists in
the API.
When you request the extents of a path, these extents are, too, first calculated
in the surface coordinate system. Then the four corners of this rectangle are
transformed into user space and a new bounding rectangle is computed.
> However,
>
> print \
> (
> ctx
> .identity_matrix()
> .new_path()
> .rotate(45 * qahirah.deg)
> .rectangle(path_rect)
> .path_extents
> )
>
> prints
>
> Rect(-0.999893, -0.999893, 1.99979, 1.99979)
ASCII art in the coordinate space including the rotation / in the context
coordinate system (the inner rectangle is what we want to draw, the outer
rectangle is described below):
2
/\
1----\
/| |\
/ | | \
0 | | 5
\ | | /
\| |/
\----4
\/
3
Same image rotated by 45° aka without the transformation / in the surface
coordinate system / what you actually draw.
0--1---2
| /\ |
| / \ |
|/ \|
|\ /|
| \ / |
| \/ |
3--4---5
In this example, we first calculate the extents in the surface space (which is
the same as your earlier example does). These are the extents seen in the bottom
image.
> Rect(-0.707031, -0.707031, 1.41406, 1.41406)
This rectangle describes the points 0, 2, 3, 5 in the above image.
These extents are then transformed to user space aka rotated by 45°. This is
equivalent to the extents of the rectangle in the first image. Notice that there
is some "free space" e.g. between the point 0 and where the rectangle actually
starts. This is why you get these larger numbers:
> Rect(-0.999893, -0.999893, 1.99979, 1.99979)
The approach implemented by cairo is a lot faster as if it would try calculating
tight extents.
I hope this clears things up.
Cheers,
Uli
--
Bitte nicht mit dem verbleibenden Auge in den Laser gucken.
- Vincent Ebert
More information about the cairo
mailing list