[cairo] [patch] enable projective transformations

Andrea Canciani ranma42 at gmail.com
Tue Aug 17 05:16:18 PDT 2010

On Tue, Aug 17, 2010 at 2:02 PM, Arjen Nienhuis <a.g.nienhuis at gmail.com> wrote:
> On Tue, Aug 17, 2010 at 1:40 PM, Andrea Canciani <ranma42 at gmail.com> wrote:
>> On Tue, Aug 17, 2010 at 1:24 PM, Arjen Nienhuis <a.g.nienhuis at gmail.com> wrote:
>>> On Tue, Aug 17, 2010 at 12:56 PM, Andrea Canciani <ranma42 at gmail.com> wrote:
>>>> On Tue, Aug 17, 2010 at 12:52 PM, Arjen Nienhuis <a.g.nienhuis at gmail.com> wrote:
>>>>>> To use it for 3D transformations you would need 4x3 (and 4x4 if you
>>>>>> want projections, too).
>>>>>> The question was: what would 3D transformations be used for?
>>>>>> (Remember: cairo uses 2D surfaces, thus the third dimension input
>>>>>> would be constant and its output would get discarded "soon")
>>>>> Use case: 2 windows with buttons that 'stick out'.
>>>>> def draw_window(ctx, w):
>>>>>  draw_background(ctx, w.background)
>>>>>  ctx.save()
>>>>>  ctx.translate_z(-10)
>>>>>  draw_buttons(ctx, w.buttons)
>>>>>  ctx.restore()
>>>>> def main():
>>>>>  draw_window(ctx, w1)
>>>>>  ctx.rotate_y(0.5)
>>>>>  ctx.translate(300, 0)
>>>>>  draw_window(ctx, w2)
>>>>> I think this needs a 4x3 matrix. You need the value of the rotation
>>>>> around the y axis to make translate_z have the right effect.
>>>> Are you saying that if you want to use 4x3 transforms (rotate_y), you
>>>> need 4x3 transforms?
>>> I'm saying:
>>> I have this use case. I think it needs rotate_y and translate_z. I
>>> think it needs 4x3 transforms.
>> Oh, if this is the case, then I can correct you easily.
>> Your use case doesn't need 3D transforms, you can obtain the same
>> effect with a 2D transforms:
>> let
>> A = [ [ a b c d ] [ e f g h ] [ i j k l ] [ m n o p ] ]
>> be your 4x4 transform (if you just want 4x3, you will have d==h==l==0 && p==1)
>> when you transform a point P [x y z w] you get:
>> P' = P * A = [ (ax+by+cz+dw), (ex+fy+gz+hw), (ix+jy+kz+lw), (mx+ny+oz+pw) ]
>> but if P is constrained to be in 2D (i.e. z==0) you get:
>> P' = P*A = [ (ax+by+dw), (ex+fy+hw), (ix+jy+lw), (mx+ny+pw) ]
>> and (assuming you won't use the output z, you will just get the same
>> as P*B, with
>> B = [ [ a b d ] [ e f g ] [ m n p ]]
> And how would that fit into my code? I'd need to calculate and keep
> track of all these matrices myself. I like the fact that cairo keeps
> track of that in 2d and i'd like cairo to also do that in 3d.
>> Notice that you are able to use projective transforms (since w is not
>> necessarily ==1).
>> Even more interesting, you can do concatenate all your 3D
>> transformations (4x4), throw away the z row and column and get a 3x3
>> matrix that does exactly what you wanted.
>> NB: concatenating, then throwing away the elements is *NOT* the same
>> as throwing away those elements, then concatenating.
> thats why Bill Spitzak said:
> I believe if you want to concatenate transforms you need to keep 12 numbers
> (a 4x3 matrix) around.
>>> Do you have better way to deal with this use case? Do you have
>>> different use cases? Is my use case useful/clear/typical?
>> The only use cases I can see for 3D transformation matrices involve 3D
>> sources/destinations (for example a path whose points are not (x,y)
>> but (x,y,z)), but I think this is beyond cairo scope.
> So, what is cairo scope then? And how would my use case fit in (if it does).
"Cairo is a 2D graphics library with support for multiple output devices."
I would assume that 3D (4D and so on) objects are out of scope.
Your use case would fit in, as you are actually only drawing 2D
objects on 2D objects.
The implementation of your use case assumes 3D transforms, but since
other implementations would be possible by living in the 2D world, I think it
is not out of scope.

More information about the cairo mailing list