# [cairo] [patch] enable projective transformations

Maarten Bosmans mkbosmans at gmail.com
Tue Aug 17 02:05:47 PDT 2010

```2010/8/17 Bill Spitzak <spitzak at gmail.com>:
> Maarten Bosmans wrote:
>>
>> This is a first attempt to add projective transformations to Cairo. It
>> is far from complete, but mostly meant to get the discussion going
>> about how such a feature should be implemented.
>
> I believe if you want to concatenate transforms you need to keep 12 numbers
> (a 4x3 matrix) around. Otherwise not enough information is remembered so
> that two "rotate about the y axis by 10 degrees" can produce the same result
> as one "rotate about the y axis by 20 degrees". The 8 number cannot
> distinguish such a rotation from a horizontal scale by 1-sin(10 degrees).

I'm not really sure what you are trying to say here. How could two
rotations possibly be the same as a scaling?

> Treating these as 3 rows (or columns) of a 4x4 matrix will allow you to
> multiply them. The last row/column will be [0,0,0,1] always, similar to the
> current Cairo matrix.

My first suggestion to look at the SVG spec was not good. For Cairo we
should stick to 2D. I don't think posititioning flat surfaces in a 3D
space and then projecting back in a 2D plane gains us anything.

> Perspective can be a single number 'D' that basically says "z makes the
> image this much smaller". This value goes in the 3rd number of that extra
> row/column. Objects at z are scaled to be 1/(1+Dz) in size.
>
> If you don't want the vanishing point to be forced to be at 0,0 then you
> need to apply transforms before and after the perspective matrix. If you
> place non-zero at that location in the matrix and multiply, the result can
> have values different than the identity in all 16 locations. So it looks
> like all 16 numbers must be stored.

There is no single vanishing point. All parallel lines vanish to one
point (possibly at infinity), but this point can be different for
different angles. Perhaps you mean the camera position, or something
similar in 3D?

> The SVG paper does correctly conclude that the final rendering does not
> require a 4x4 matrix if the source object is a flat plane with everything at
> z = 0. Since z = 0 an entire column of the matrix is ignored, and since the
> output z is not relevant (only the w is) an entire row is ignored. Deleting
> this row and column and get a 3x3 matrix that translates x,y,1 into wx,wy,w.
> However this matrix is useless for concatenating transforms. Still it might
> be the API to pixman.

This 3x3 matrix is indeed what is used in pixman. And I propose to use
such a matrix in Cairo to, normalized such that the bottom right
element is always 1.

> In conclusion:
>
> I think the internal matrix may have to be 4x4 with all 16 numbers unknown
> so that Cairo can remain transform-independent.
>
> Final rendering only requires 9 of the 16 numbers in the CTM if the objects
> are actually "2D".
>
> I do like the SVG/CSS spec of just saying "perspective" with one number.
> Would prefer to directly specify it as zero means "flat".

As an example, attached are some thing you can do with the projective
transformations in cairo. The blue dashed line is the unit square.
Inside the square are an image surface and a black stroked rectangle,
drawn by cairo.

The left has a unit transform.
The second has the px value set to 1.0. The matrix thus looks like
[ 1  0  0 ]
[ 0  1  0 ]
[ 1  0  1 ]
In the third square first a (0, -0.5) translation is applied, followed
by the perspective matrix as above and finally it is translated back
by (0, 0.5). This has the effect that the vanishing point for
horizontal lines now lies at (1, 0.5).

So you can combine transformations perfectly well. The last example is
similar to how you would rotate around an arbitrary point by pre- and
post-translating.

As you can clearly see in the third square, there are still some bugs,
because the image surface drawn by pixman should coincide with the

Maarten
-------------- next part --------------
A non-text attachment was scrubbed...
Name: projective_sample.png
Type: image/png
Size: 12011 bytes
Desc: not available
URL: <http://lists.cairographics.org/archives/cairo/attachments/20100817/9520b485/attachment-0001.png>
```