[Tex/LaTex] Tikz rotation center not where I thought it would be

tikz-pgf

I am trying to rotate a rectangle drawn in tikz. Many questions on this site were helpful about tikz rotations but for me personally I seem to be misusing one of the parameters, as my intended center of rotation (red dot in the figure below) doesn't seem to be the center of rotation for the rectangle. I want the rectangle to be centered over the red dot, but angled relative to it's horizontal center. The rotation angle looks okay, just not rotated about the correct point (as depicted below).

enter image description here

\documentclass{article}

\usepackage[%
    papersize={100mm,100mm},
]{geometry}
\usepackage{atbegshi}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}
\usetikzlibrary{backgrounds}
\usetikzlibrary{automata}

%http://tex.stackexchange.com/questions/229279/how-can-i-make-a-perfect-page-grid-that-fits-my-page-for-measuring-purposes-in-t
\newcommand{\showgrid}{%
    \begin{tikzpicture}
    [
        shift={(current page.center)},
        x=1mm,y=1mm,
        overlay,
        remember picture,
        inner sep=0pt,
        outer sep=0pt,
        minor line/.style={help lines, draw=gray!25, on background layer},
        major line/.style={help lines, draw=gray},
    ]
    \pgfmathtruncatemacro\xmaxstep{\paperwidth/1mm}% calculate needed steps in x direction
    \pgfmathtruncatemacro\ymaxstep{\paperheight/1mm}% calculate needed steps in y direction
    % Vertical lines (events in distinct columns)
    \foreach \step in {0,...,\xmaxstep} {
        \pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,5)),0),"major line","minor line")}%
        \draw [\gridlineconfig] ($(current page.north west) + (\step mm,0)$) -- ($(current page.south west) + (\step mm,0)$);
    }
    % Horizontal lines (events in distinct rows)
    \foreach \step in {0,...,\ymaxstep} {
        \pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,5)),0),"major line","minor line")}%
        \draw [\gridlineconfig] ($(current page.north west) - (0,\step mm)$) -- ($(current page.north east) - (0,\step mm)$);
        %\node [anchor=north] at ($ (current page.north west) + (\step mm,0) $) {}; % add text coordinates along the top
        %\node [anchor=west] at ($ (current page.north west) - (0,\step mm) $) {};  % add text coordinates along the LHS
    }
    \end{tikzpicture}
}
\tikzset{dot/.style={circle,fill=#1,inner sep=0,minimum size=4pt}}

\begin{document}\thispagestyle{empty}

\showgrid

\begin{tikzpicture}%[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
[
shift={(current page.center)},
x=1mm,y=1mm,
overlay,
remember picture
]

\node [dot=black] (Point1) at (0,0) {};

\node [dot=red] (ExpectedCentre) at ($(Point1.center) + (-0.5 in,0)$) {};


\draw[black, line width=0.55mm, rotate around={45:($(Point1.center) + (-0.5 in,0)$)}] ($(Point1.center) + (-0.5 in - 0.5 mm, 5 mm)$) rectangle ($(Point1.center) + (-0.5 in + 0.5 mm, -5 mm)$);

\end{tikzpicture}
\end{document}

UPDATE

I've been trying to implement CFR's solution below, but I have still been unable to implement a successful rotation about a point that is not (0,0)
The MWE has been trimmed further:

\documentclass[tikz,border=10pt,multi]{standalone}
\usetikzlibrary{calc}
\tikzset{dot/.style={circle,fill=#1,inner sep=0,minimum size=4pt}}
\begin{document}
\begin{tikzpicture}[x=1mm,y=1mm]

\node [dot=black] (Point2) at (2,1) {};

\path ($(Point2.center) + (-0 in,0)$) coordinate (c) node [dot=red] {};

\draw[black, line width=0.55mm, rotate around={45:(c)}] ($(0,0) + ({-0 in - 0.5 mm}, 5 mm)$) rectangle ($(0,0) + ({-0 in + 0.5 mm}, -5 mm)$);

\end{tikzpicture}
\end{document}

Best Answer

I'm not sure why you made the MWE so complicated. As far as I can tell, the basic problem is the use of the named coordinate, which is not transformed as part of the rotation of the coordinate system. If that is replaced by the appropriate coordinates, which are subject to the transformation, then everything works as expected.

The following first shows the problem, to demonstrate the sufficiency of the MWE, and second the resolution, when points not influenced by the rotation are replaced by points which are.

problem and resolution

That is, (Point1), for example, is not affected by the coordinate transformation set with rotate around, while (0,0) is.

\documentclass[tikz,border=10pt,multi]{standalone}
\usetikzlibrary{calc}
\tikzset{dot/.style={circle,fill=#1,inner sep=0,minimum size=4pt}}
\begin{document}
\begin{tikzpicture}
  [
    x=1mm,
    y=1mm,
  ]
  \node [dot=black] (Point1) at (0,0) {};
  \path ($(Point1.center) + (-0.5 in,0)$)  node (n)  [dot=red] {};
  \draw[gray, line width=0.55mm] ($(Point1.center) + ({-0.5 in - 0.5 mm}, 5 mm)$) rectangle ($(Point1.center) + ({-0.5 in + 0.5 mm}, -5 mm)$);
  \draw[black, line width=0.55mm, rotate around={45:(n)}] ($(Point1.center) + ({-0.5 in - 0.5 mm}, 5 mm)$) rectangle ($(Point1.center) + ({-0.5 in + 0.5 mm}, -5 mm)$);
  \begin{scope}[yshift=-20mm]
    \node [dot=black] (Point2) at (0,0) {};
    \path ($(Point2.center) + (-0.5 in,0)$) coordinate (c) node [dot=red] {};
    \draw[gray, line width=0.55mm] ($(Point2.center) + ({-0.5 in - 0.5 mm}, 5 mm)$) rectangle ($(Point2.center) + ({-0.5 in + 0.5 mm}, -5 mm)$);
    \draw[black, line width=0.55mm, rotate around={45:(c)}] ($(0,0) + ({-0.5 in - 0.5 mm}, 5 mm)$) rectangle ($(0,0) + ({-0.5 in + 0.5 mm}, -5 mm)$);
  \end{scope}
\end{tikzpicture}
\end{document}

UPDATE

To see what's going on, it is easiest to concentrate on a single point. Here's an illustration:

rotate around demo

This is not what TikZ does, but it is useful to think of it as if it did the following. Suppose we ask it to rotate a path around (2,1) by 45 degrees.

  1. Figure out where the untransformed objects would be.
  2. Now move to (2,1).
  3. From here, figure out where each point on the untransformed path is as a polar coordinate i.e. (<angle>:<distance from here>).
  4. For each calculated polar coordinate, increase <angle> by 45 degrees.
  5. Now use the resulting coordinates in place of the original ones to construct the path.

Code:

\documentclass[tikz,border=10pt,multi]{standalone}
\tikzset{
  dot/.style={circle, fill=#1, inner sep=0, minimum size=4pt},
  mini dot/.style={circle, inner sep=0pt, minimum size=2pt, pos=1, fill, node contents={}},
}
\begin{document}
\begin{tikzpicture}[x=3mm,y=3mm]
  \path (2,1) coordinate (c) node [dot=red] {};
  \draw[black, opacity=.5, line width=0.55] (-.5, 5) rectangle (.5, -5);
  \draw[black, opacity=.5, line width=0.55, rotate around={45:(c)}] (-.5, 5) rectangle (.5, -5);
  \draw [blue]
    (c) edge   node (p1) [mini dot] ++({atan((5-1)/(.5-2))}:-{sqrt((5-1)^2+(.5-2)^2)})
    -- ++({atan((5-1)/(.5-2))+45}:-{sqrt((5-1)^2+(.5-2)^2)})  node (q1) [mini dot]
    ;
  \draw [blue, ->] (p1) arc ({atan((5-1)/(.5-2))}:{atan((5-1)/(.5-2))+45}:-{sqrt((5-1)^2+(.5-2)^2)}) ;
\end{tikzpicture}
\end{document}

EDIT

Here's an example which tries to answer both the 'update' to the question (i.e. the new question being smuggled in as part of 'the' question) and the question Stefan asked about why you might want your named coordinates to stay put.

Consider, then, the following example.

colourful example of rotations and scopes

This is drawn using three series of rotate arounds. Each roughly circular set of objects is created using 8 rotations around the central point. None of these central points are the origin. Within each series, the 8 rotations differ in the angle of rotation. Between each series, the rotations differ in the point about which the rotation is done.

For the first and third of the series, named coordinates or nodes are defined as part of each rotation.

The positions created within the third series (at the top) are then used to add the green parts of the picture in the background. Part of this is done within the rotational scopes. However, the large central green object is drawn later and relies crucially on knowing where the defined points are within the overall picture and independent of the rotational scope. This is much easier --- and, I think, more natural --- than trying to compensate for the original rotation when drawing the green central bit later.

\PassOptionsToPackage{rgb,x11names,dvipsnames,svgnames}{xcolor}
\documentclass[tikz,border=10pt,multi]{standalone}
\usetikzlibrary{backgrounds,hobby}
\begin{document}
\begin{tikzpicture}
  \coordinate (o) at (0,0);
  \coordinate (g) at ([yshift=-40mm]o);
  \foreach \i/\j in {(-35mm,0)/a,(35mm,0)/b,(0,40mm)/c} \path \i coordinate (\j) ;
  \foreach \i [count=\n from 0, evaluate=\n as \c using {\n < 5 ? 100*(1-\n/4) : 100*(\n/4 - 1 ) }] in {0,45,...,315}
  {
    \begin{scope}[rotate around={\i:(-35mm,0)}]
      \path [inner color=white, outer color=WildStrawberry!\c!Purple4] (-35mm,0) -- ++(-20:20mm) arc (-20:20:-20mm) node (a\n) [midway, shift=(\i:2.5mm), circle, ball color=WildStrawberry!\c!Purple4] {} -- cycle;
    \end{scope}
    \begin{scope}[rotate around={\i:(35mm,0)}]
      \path [outer color=blue!\c!cyan, inner color=white] (35mm,0) -- ++(-20:25mm) arc (-20:20:25mm) -- cycle;
    \end{scope}
    \begin{scope}[rotate around={\i:(0,40mm)}]
      \path [inner color=white, outer color=WildStrawberry!\c!Gold1] (0,40mm) -- ++(-20:20mm) arc (-160:-200:20mm) node (c\n) [midway, shift=(\i:2.5mm), circle, ball color=WildStrawberry!\c!Gold1] {} -- cycle;
      \scoped[on background layer] {\path [draw=Green4, bottom color=Green4, top color=Green1!25] (c\n.\i) [out=-75,in=-20] to (c) [out=20, in=75] to (c\n.\i);}
    \end{scope}
  }
  \begin{scope}[on background layer]
    \path  (c5.-120) ++(-90:4mm) coordinate (c5d);
    \path  (c7.-60) ++(-90:4mm)  coordinate (c7d);
    \path [top color=white, bottom color=Green4, middle color=Green1] ([yshift=-5mm]c6.-90)
    [
      closed,
      curve through={
        ([tension out=5, tension in=-1]c7d)
        ([tension out=4, tension in=5]10mm,15mm)
        (5mm,-15mm)
        ([xshift=1mm]g)
        ([xshift=-1mm]g)
        (-5mm,-15mm)
        ([tension in=4, tension out=5]-10mm,15mm)
        ([tension in=5, tension out=-1]c5d)
      }
    ] to cycle;
  \end{scope}
\end{tikzpicture}
\end{document}