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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.