# [cairo] The right approach to projective transformations

Bill Spitzak spitzak at gmail.com
Tue Aug 31 10:48:41 PDT 2010

```
M Joonas Pihlaja wrote:
> On Mon, 30 Aug 2010, Behdad Esfahbod wrote:
>
>> I think if we are doing this projective thing, we should finally switch to an
>> opaque transformation struct.  This allows for the transformation to be
>> intelligently caching.  Cache the inverse, cache the determinant, cache
>> whether it's an integer translation only, etc.
>
> I think we can do this without making the existing transform API
> obsolete.  Factor the complete mapping into two parts: a 2d affine map
> followed by a more powerful projective map, and the existing transform
> calls only work on the 2d affine part.  Existing client rendering
> routines can then pretend they're drawing onto a normal plane as
> before, even if that plane is twisted about later by a projective
> part.

That is exactly what the proposed 3x3 matrix does. The existing 2D
transforms can be easily converted to 3x3 matrix by adding a bottom row
of 0,0,1 and multiplied by the existing one, and will then concatentate
and produce the desired result.

You can't split this into "two steps" because otherwise attempts to do
2D translations after a 3D transform are set up will not produce the
desired result. For instance, Cairo functions will expect that drawing a
0,0,1,1 square at a .5 scale will produce the same image as drawing a
0,0,.5,.5 square. If you do "two steps" then the .5 scale would produce
the result of doing the .5 scale *before* the perspective transform and
thus produce a different result.

Also I am pretty certain that you cannot do this in any more efficient
way than a 3x3 matrix multiply. Flags indicating aspects of the matrix
contents (such as the bottom row being 0,0,1) can be used to skip
multiplies to speed it up. But the basic algorithm is a 3x3 matrix.

```