[cairo-commit] [cairo-www] src/cookbook src/cookbook.mdwn

Nis Martensen nmartensen at freedesktop.org
Fri Nov 20 13:04:19 PST 2015


 src/cookbook.mdwn                       |    1 +
 src/cookbook/transform_about_point.mdwn |   28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

New commits:
commit a37cdaad1994d4eca4a48885310ef203d9249bd1
Author: Lawrence D'Oliveiro <ldo at geek-central.gen.nz>
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.


More information about the cairo-commit mailing list