# Rotating around computed point using PGF

I am trying to rotate a drawing around a specific point using PGF commands. As long as I hard code the center of rotation, this works just fine:

\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\draw[style=help lines] (0,0) grid[step=1cm] (3, 3);
% Rotate around (1, 1).
\pgftransformshift{\pgfpointxy{1}{1}}
\pgftransformrotate{20}
\pgftransformshift{\pgfpointxy{-1}{-1}}
\draw (0.5, 0.5) -- (1.5, 1.5);
\draw (1.5, 0.5) -- (0.5, 1.5);
\end{tikzpicture}
\end{document}


But I don't want to rotate around a hard coded center but around a computed one. I compute my center using \coordinate (x) at ($<some computation$);. I tried the following:

\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\draw[style=help lines] (0,0) grid[step=1cm] (3, 3);
\coordinate (x) at (1, 1); % In real life: ($<computation>$)
\pgftransformshift{\pgfpointscale{1}{\pgfpointanchor{x}{center}}}
\pgftransformrotate{20}
\pgftransformshift{\pgfpointscale{-1}{\pgfpointanchor{x}{center}}}
\draw (0.5, 0.5) -- (1.5, 1.5);
\draw (1.5, 0.5) -- (0.5, 1.5);
\end{tikzpicture}
\end{document}


Now what seems to happen is that the coordinate specified in the second shift is affected by the preceding \pgftransformrotate, even though I defined it before the transformations. Thus, the drawing is offset in the second example.

Can I somehow prevent my computed center of rotation from being transformed by the pgftransform commands? Or is there any other solution to my problem?

-

There are surely other solutions but the first one can be :

\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\newdimen\myx
\newdimen\myy

\begin{tikzpicture}
\draw[style=help lines] (0,0) grid[step=1cm] (3, 3);
\coordinate (x) at (1, 1); % In real life: ($<computation>$)
\pgfextractx{\myx}{\pgfpointanchor{x}{center}}
\pgfextracty{\myy}{\pgfpointanchor{x}{center}}
\draw[red] (0.5, 0.5) -- (1.5, 1.5) (1.5, 0.5) -- (0.5, 1.5);
\pgftransformshift{\pgfqpoint{\myx}{\myy}}
\pgftransformrotate{20}
\pgftransformshift{\pgfqpoint{-\myx}{-\myy}}
\draw[blue] (0.5, 0.5) -- (1.5, 1.5) (1.5, 0.5) -- (0.5, 1.5);
\end{tikzpicture}

\end{document}


-
Great hint, thank you! I wrapped your solution into macros (see my answer) and it works like a charm. – hc_ Mar 23 '12 at 14:39

First a simple TikZ solution:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\begin{tikzpicture}
\draw[style=help lines] (0,0) grid[step=1cm] (3, 3);
\coordinate (x) at (2, 2); % In real life: ($<computation>$)
\begin{scope}[rotate around={45:(x)}]
\draw (0.5, 0.5) -- (1.5, 1.5);
\draw (1.5, 0.5) -- (0.5, 1.5);
\end{scope}
\end{tikzpicture}
\end{document}


Second, the PGF version:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\begin{tikzpicture}
\draw[style=help lines] (0,0) grid[step=1cm] (3, 3);
\coordinate (x) at (2, 2); % In real life: ($<computation>$)
\node[fill,circle,inner sep=0.5mm] (O) at (x) {};
\pgftransformshift{\pgfpointanchor{x}{center}}
\pgfgetlastxy{\myx}{\myy}
\pgftransformrotate{20}
\pgftransformshift{\pgfpoint{-\myx}{-\myy}}%This has no effect if x used, x is the origin now
\draw (0.5, 0.5) -- (1.5, 1.5);
\draw (1.5, 0.5) -- (0.5, 1.5);
\end{tikzpicture}
\end{document}


-

I ended up using Altermundus' solution but to reduce clutter, I introduced two macros:

\def\savePoint#1#2{%
\expandafter\newdimen\csname #2x\endcsname\expandafter\pgfextractx\csname #2x\endcsname{\pgfpointanchor{#1}{center}}
\expandafter\newdimen\csname #2y\endcsname\expandafter\pgfextracty\csname #2y\endcsname{\pgfpointanchor{#1}{center}}}
\def\getPoint#1{\pgfpoint{\csname #1x\endcsname}{\csname #1y\endcsname}}


Now I write a little more compact code:

  \coordinate (x) at (1, 1);
\savePoint{x}{x}
\pgftransformshift{\pgfpointscale{1}{\getPoint{x}}}
\pgftransformrotate{20}
\pgftransformshift{\pgfpointscale{-1}{\getPoint{x}}}


\pgfgetlastxy like percusse is another solution but you need to place it correctly. – Alain Matthes Mar 23 '12 at 16:11