PATCH cairo-www: New Cookbook Example: Transforming About An Arbitrary Point
Lawrence D'Oliveiro <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Organization | Geek Central |
| Message-ID | <[email protected]> |
Cairo provides functions for applying scaling and rotation about the origin, but not about an arbitrary point. I don’t think the issue of how to do transformations about an arbitrary point is covered in any of the existing wiki examples, so here is a new cookbook example to provide that. -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo
transform_about_point.patch
(text/x-patch, 2.9 KB)
commit 4052b2d483a4ccb003f984cab96730e5f13b270d Author: Lawrence D'Oliveiro <[email protected]> Date: Thu Nov 19 21:53:36 2015 +0000 New cookbook example: Transforming About An Arbitrary Point diff --git a/src/cookbook.mdwn b/src/cookbook.mdwn index 741bb6d..cc78db9 100644 --- a/src/cookbook.mdwn +++ b/src/cookbook.mdwn @@ -11,6 +11,7 @@ * [[Load_jpg/png/gif/bmp/etc_into_CairoContext_with_help_from_gdk-pixbuf_in_Pycairo/Pygtk|gdkpixbufpycairo]] * [[Basic_matrix_transformation_reminder|matrix_transform]] * [[Keeping Your Matrix Transformations Straight|matrix_conventions]] +* [[Transforming About An Arbitrary Point|transform_about_point]] * [[Python:_Converting_PIL_images_to_Cairo_surfaces_and_back|pythoncairopil]] * [[Loading_fonts_using_FreeType_for_cairo_use_in_Python|freetypepython]] * [[A_description_of_compositing_operators_in_Cairo|operators]] diff --git a/src/cookbook/transform_about_point.mdwn b/src/cookbook/transform_about_point.mdwn new file mode 100644 index 0000000..117e34c --- /dev/null +++ b/src/cookbook/transform_about_point.mdwn @@ -0,0 +1,28 @@ +[[!meta title="Transforming About An Arbitrary Point"]] + +Cairo provides functions for doing rotations and scaling about the origin: <tt>cairo_rotate()</tt> and <tt>cairo_scale()</tt> for directly affecting the transformation matrix of a context, and <tt>cairo_init_rotate()</tt>/<tt>cairo_rotate()</tt> and <tt>cairo_init_scale()</tt>/<tt>cairo_scale()</tt> for computing a transformation matrix separately from a context. But what if you want to perform rotation or scaling about a point *other* than the origin? + +In fact, this is quite simple. Break up the transformation into 3 separate steps: + + 1. perform a translation that moves the specified point to the origin + 2. perform the desired rotation or scaling about the origin + 3. perform the inverse of the translation in step 1, moving the origin + back to the specified point. + +In Cairo code, these steps have to be performed in the reverse order (see [[here|matrix_conventions]] for why). Supposing we want to rotate by *angle* radians about the point (*centre_x*, *centre_y*). The code would look like + + cairo_translate(cr, centre_x, centre_y); /* step 3 */ + cairo_rotate(cr, angle); /* step 2 */ + cairo_translate(cr, - centre_x, - centre_y); /* step 1 */ + +where the comments refer to the steps in the previous list. + +Similarly, if we wanted to compute such a transformation as a separate matrix for use later, we could do it like + + cairo_matrix_t mat; + cairo_matrix_init_identity(&mat); + cairo_matrix_translate(&mat, centre_x, centre_y); /* step 3 */ + cairo_matrix_rotate(&mat, angle); /* step 2 */ + cairo_matrix_translate(&mat, - centre_x, - centre_y); /* step 1 */ + +Here I could have used <tt>cairo_matrix_init_translate()</tt> to combine the first two Cairo calls into one, but I kept them separate so it is clear that the second call corresponds exactly to step 3 in the above list.