Cannot get transformations to work

View: New views
6 Messages — Rating Filter:   Alert me  

Cannot get transformations to work

by ashley-33 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi, I'm using cairo, compiled on Windows under Visual Studio Express 2008.
Pretty much everything works, and its possible this could be a bug due to
my compilation. I think its more likely I'm just doing something dumb.

I can't seem to get any transformations to work, here is my code:

        // create 24bit RGB drawing surface of the appropriate size
        cairo_surface_t *cairoSurface =
                cairo_image_surface_create(CAIRO_FORMAT_RGB24, 500, 500);
        cairo_t *cairoState = cairo_create(cairoSurface);

        // set its background to white
        cairo_set_source_rgb(cairoState,1, 1, 1);
        cairo_rectangle(cairoState,0,0,500,500);
        cairo_fill(cairoState);

        // define arrow object
        double arrowHeadAngle = 2*M_PI/360*45;
        double arrowLength = 50;
        cairo_t *arrowState = cairo_create(cairoSurface);
        cairo_set_line_width (arrowState, 1);
        // define arrow body
        cairo_new_path(arrowState);
        double arrowStartX = 0;
        double arrowStartY = 0;
        cairo_move_to(arrowState,arrowStartX,arrowStartY);
        double arrowEndX = arrowStartX + arrowLength;
        double arrowEndY = arrowStartY;
        cairo_line_to(arrowState,arrowEndX,arrowEndY);
        // define arrow head left
        cairo_arc(arrowState,arrowEndX,arrowEndY,arrowLength*0.2,M_PI-arrowHeadAngle,M_PI);
        cairo_line_to(arrowState,arrowEndX,arrowEndY);
        // define arrow head right
        cairo_arc(arrowState,arrowEndX,arrowEndY,arrowLength*0.2,M_PI,M_PI+arrowHeadAngle);
        cairo_line_to(arrowState,arrowEndX,arrowEndY);

        // draw arrow
        cairo_matrix_t* cairoMatrix = new cairo_matrix_t;
        cairo_matrix_init_identity(cairoMatrix);
        cairo_set_matrix(arrowState,cairoMatrix);
        cairo_set_source_rgb(arrowState,0,1,0);
        cairo_stroke_preserve(arrowState);

        // draw rotated and translated version of arrow
        cairo_translate(arrowState,100,100);
        cairo_rotate(arrowState,M_PI/2);
        cairo_set_source_rgb(arrowState,1,0,0);
        cairo_stroke_preserve(arrowState);

        // cleanup the cairo stuff
        cairo_surface_write_to_png (cairoSurface, "test.png");
    cairo_surface_destroy(cairoSurface);
        cairo_destroy(cairoState);
        cairo_destroy(arrowState);

No matter what I do, I cannot seem to get the arrow to be drawn anywhere
else but the origin without rotation. The calls to translate and rotate
appear to do nothing. I checked its error status and all calls return
success. The arrow is red, so the second call to cairo_stroke_preserve is
definitely writing to the surface.

Am I doing something obviously incorrect here in my usage?

Thanks

Ashley Mills

P.S. Great library :)



_______________________________________________
cairo mailing list
cairo@...
http://lists.cairographics.org/mailman/listinfo/cairo

Re: Cannot get transformations to work

by Kalle Vahlman :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/10/20  <ashley@...>:
[snip]
> Am I doing something obviously incorrect here in my usage?

Yes, as the transformations only apply to paths drawn *after* the
calls to _translate() and _rotate().

So you can't "move" the path after defining it. To do that there's
three options (of which I'm aware):

 * copy the path with cairo_copy_path() and add it back after
translating using cairo_append_path()
 * separate the arrow drawing to a function and call it twice
 * render the arrow to a temporary surface and translating that

The last option is probably going to be the fastest, but is also
subject to rasterization so the quality might not be satisfactory. The
second is what people usually do I think.

Cairo gurus please correct me if I'm talking silly talk :)

--
Kalle Vahlman, zuh@...
Powered by http://movial.com
Interesting stuff at http://sandbox.movial.com
See also http://syslog.movial.fi
_______________________________________________
cairo mailing list
cairo@...
http://lists.cairographics.org/mailman/listinfo/cairo

Re: Cannot get transformations to work

by ashley-33 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> 2009/10/20  <ashley@...>:
> [snip]
>> Am I doing something obviously incorrect here in my usage?
>
> Yes, as the transformations only apply to paths drawn *after* the
> calls to _translate() and _rotate().

I see. I suppose you already guessed this: I was imagining that the path
vertices themselves were being transformed.

> So you can't "move" the path after defining it. To do that there's
> three options (of which I'm aware):
>
>  * copy the path with cairo_copy_path() and add it back after
> translating using cairo_append_path()
>  * separate the arrow drawing to a function and call it twice
>  * render the arrow to a temporary surface and translating that

OK I'll just write it as a function instead for now. Thanks.

I assume then that 3rd option would be the standard way to transform a
bunch of points?

How would one go about copying the temporary surface back onto the
original surface?

> The last option is probably going to be the fastest, but is also
> subject to rasterization so the quality might not be satisfactory. The
> second is what people usually do I think.

What would be subject to rasterization? The printing onto the temporary
surface? Oh I see, so then the surfaces would be combined by simply adding
them together according to opacity?

Thanks

Ashley


_______________________________________________
cairo mailing list
cairo@...
http://lists.cairographics.org/mailman/listinfo/cairo

Re: Cannot get transformations to work

by mkbosmans :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/10/20  <ashley@...>:
> I see. I suppose you already guessed this: I was imagining that the path
> vertices themselves were being transformed.

May be the text on this page can help you understand the transformations better.
http://cairographics.org/tutorial/#L2linewidth
Note that how the path of both circles is transformed by the
cairo_scale call, but only the line width of the left one distorded.

> OK I'll just write it as a function instead for now. Thanks.

Tip: It is generally a good idea to start and end drawing functions
with a cairo_save and cairo_restore call, like in the example linked
above. This way you can apply the transformations you need to get the
arrow in the right place, without affecting other drawing routines
outside your arrow-function.

> I assume then that 3rd option would be the standard way to transform a
> bunch of points?

I would only choose this option if you need it for performance reasons.

> How would one go about copying the temporary surface back onto the
> original surface?

cairo_set_source_surface followed by a cairo_paint or a path fill.

>> The last option is probably going to be the fastest, but is also
>> subject to rasterization so the quality might not be satisfactory. The
>> second is what people usually do I think.
>
> What would be subject to rasterization? The printing onto the temporary
> surface? Oh I see, so then the surfaces would be combined by simply adding
> them together according to opacity?

Yep, or according to any other blend mode operator you choose.
Remember that you probably want whole pixel offsets when compositing
the temporary surface back on your drawing surface.

> Thanks
>
> Ashley

Maarten
_______________________________________________
cairo mailing list
cairo@...
http://lists.cairographics.org/mailman/listinfo/cairo

Re: Cannot get transformations to work

by ashley-33 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I was thinking about this.

I wrote a function in the end.

Would it perhaps be useful to add this functionality to Cairo? It seems
like it might be something which comes up quite a lot; the transformation
of a set of points rather than the drawing surface.

Would it be difficult to add this to the code base?

Ashley

> 2009/10/20  <ashley@...>:
>> I see. I suppose you already guessed this: I was imagining that the path
>> vertices themselves were being transformed.
>
> May be the text on this page can help you understand the transformations
> better.
> http://cairographics.org/tutorial/#L2linewidth
> Note that how the path of both circles is transformed by the
> cairo_scale call, but only the line width of the left one distorded.
>
>> OK I'll just write it as a function instead for now. Thanks.
>
> Tip: It is generally a good idea to start and end drawing functions
> with a cairo_save and cairo_restore call, like in the example linked
> above. This way you can apply the transformations you need to get the
> arrow in the right place, without affecting other drawing routines
> outside your arrow-function.
>
>> I assume then that 3rd option would be the standard way to transform a
>> bunch of points?
>
> I would only choose this option if you need it for performance reasons.
>
>> How would one go about copying the temporary surface back onto the
>> original surface?
>
> cairo_set_source_surface followed by a cairo_paint or a path fill.
>
>>> The last option is probably going to be the fastest, but is also
>>> subject to rasterization so the quality might not be satisfactory. The
>>> second is what people usually do I think.
>>
>> What would be subject to rasterization? The printing onto the temporary
>> surface? Oh I see, so then the surfaces would be combined by simply
>> adding
>> them together according to opacity?
>
> Yep, or according to any other blend mode operator you choose.
> Remember that you probably want whole pixel offsets when compositing
> the temporary surface back on your drawing surface.
>
>> Thanks
>>
>> Ashley
>
> Maarten
>


_______________________________________________
cairo mailing list
cairo@...
http://lists.cairographics.org/mailman/listinfo/cairo

Re: Cannot get transformations to work

by Behdad Esfahbod-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 11/03/2009 04:24 AM, ashley@... wrote:
> I was thinking about this.
>
> I wrote a function in the end.
>
> Would it perhaps be useful to add this functionality to Cairo? It seems
> like it might be something which comes up quite a lot; the transformation
> of a set of points rather than the drawing surface.

You can do this already:

   - cairo_save()
   - transform
   - add path
   - cairo_restore()
   - cairo_copy_path()
   - cairo_new_path()

If you want the inverse, do the transform before copy_path().

behdad


> Would it be difficult to add this to the code base?
>
> Ashley
>
>> 2009/10/20<ashley@...>:
>>> I see. I suppose you already guessed this: I was imagining that the path
>>> vertices themselves were being transformed.
>>
>> May be the text on this page can help you understand the transformations
>> better.
>> http://cairographics.org/tutorial/#L2linewidth
>> Note that how the path of both circles is transformed by the
>> cairo_scale call, but only the line width of the left one distorded.
>>
>>> OK I'll just write it as a function instead for now. Thanks.
>>
>> Tip: It is generally a good idea to start and end drawing functions
>> with a cairo_save and cairo_restore call, like in the example linked
>> above. This way you can apply the transformations you need to get the
>> arrow in the right place, without affecting other drawing routines
>> outside your arrow-function.
>>
>>> I assume then that 3rd option would be the standard way to transform a
>>> bunch of points?
>>
>> I would only choose this option if you need it for performance reasons.
>>
>>> How would one go about copying the temporary surface back onto the
>>> original surface?
>>
>> cairo_set_source_surface followed by a cairo_paint or a path fill.
>>
>>>> The last option is probably going to be the fastest, but is also
>>>> subject to rasterization so the quality might not be satisfactory. The
>>>> second is what people usually do I think.
>>>
>>> What would be subject to rasterization? The printing onto the temporary
>>> surface? Oh I see, so then the surfaces would be combined by simply
>>> adding
>>> them together according to opacity?
>>
>> Yep, or according to any other blend mode operator you choose.
>> Remember that you probably want whole pixel offsets when compositing
>> the temporary surface back on your drawing surface.
>>
>>> Thanks
>>>
>>> Ashley
>>
>> Maarten
>>
>
>
> _______________________________________________
> cairo mailing list
> cairo@...
> http://lists.cairographics.org/mailman/listinfo/cairo
>
_______________________________________________
cairo mailing list
cairo@...
http://lists.cairographics.org/mailman/listinfo/cairo