[cairo] Transformations usage
Bill Spitzak
spitzak at gmail.com
Wed Dec 6 18:29:33 UTC 2017
It is probably easier to use a series of cairo transforms. But I
think the main problem is that the y in the matrix needs to be
height-offset.
If you have a point XY in your map that you want to be in the center
of the window, I would do this:
cairo_translate(cr, -X, -Y); // put center at 0,0
cairo_scale(cr, 1, -1); // flip from y-up to y-down
cairo_rotate(cr, r); // rotate ccw by r degrees
cairo_scale(cr, s, s); // scale where s is pixels/meter
cairo_translate(cr, w/2, h/2); // move center back to center of
window of size w×h
On Wed, Dec 6, 2017 at 2:46 AM, Daniele Dario <d.dario76 at gmail.com> wrote:
> Hello everyone,
> I'm trying to create my own widget on GTK+ to display a clip of a 2D
> map where I placed some polygons. The point of view can be moved inside
> the map and may rotate.
>
> The main idea is that I draw the map on a cairo_surface_t once and than
> on expose event I use coordinates of POV to center the device surface
> to paint on the map, rotate the map, scale, clip and paint.
>
> To start I tried to use a transformation matrix to be able to draw
> using native coordinates on a surface but I'm getting confused on how
> transformation affects drawing.
>
> At the end of the code below I expect to have a map painted on the
> surface. In order to paint it on the widget I'd need another
> transformation because:
> - map size in the example is 165x165 and scale is 1 pixel = 1 [m]
> - widget will have a different ratio
>
> Can someone point me out on some examples or with some hint on how to
> achieve what I'm looking for?
>
> Thanks in advance,
> Daniele.
>
> /*
> * Create a surface for the map:
> * - 1 pixel = 1 [m]
> * - assume map width >= height
> * - coordinates of polygons are relative to an
> * arbitrary origin placed at
> * O = (x = height/2, y = height/2)
> */
> gint site_width = 165;
> gint site_height = 165;
> cairo_surface_t *map = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
> site_width, site_height);
>
> /* Origin coordinates are relative */
> gdouble offset = site_height / 2.;
>
> /* Create a context to draw on the surface */
> cr = cairo_create (map);
>
> /*
> * FIXME: Need a transformation in order to use
> * coordinates relative to O:
> * - x axis is correct just needs translation of offset
> * - y axis is inverse and needs translation of offset
> */
> cairo_matrix_t mat;
> cairo_matrix_init (&mat, 1.0, 0.0, 0.0, -1.0, offset, offset);
> cairo_transform (cr, &mat);
>
> /* TODO: draw all objects on the map */
> /* Array of (x,y) coordinates to represent a polygon */
> GtkScuiPoint v1 [4] = {
> { -20., -40.},
> { -20., 0.},
> { -50., 0.},
> { -50., -40.}
> };
>
> //cairo_set_line_width (cr, 0.1);
>
> cairo_set_source_rgba (cr, 1., 0., 0., .7);
>
> /* Wrapper to draw and fill polygon */
> scui_cairo_draw_polygon (cr, TRUE, v1, 4);
>
> GtkScuiPoint v2 [4] = {
> { 40., 0.},
> { 40., 20.},
> { 20., 20.},
> { 20., 0.}
> };
>
> cairo_set_source_rgba (cr, 0., 0., 1., .7);
>
> /* Wrapper to draw an empty polygon */
> scui_cairo_draw_polygon (cr, FALSE, v2, 4);
>
> /* TODO: Store surface to avoid re-painting it */
>
> /* Destroy context */
> cairo_destroy (cr);
>
>
> --
> cairo mailing list
> cairo at cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo
More information about the cairo
mailing list