Re: Transformations usage
Bill Spitzak <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <CAL-8oAie7QZ+kf4dZmRTDJOP9Tr1a=zhzqXuXK5qWHjMPbM7KA@mail.gmail.com> |
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 <[email protected]> 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 > [email protected] > https://lists.cairographics.org/mailman/listinfo/cairo -- cairo mailing list [email protected] https://lists.cairographics.org/mailman/listinfo/cairo