How to allow labels' anchors in TikZ to be affected by rotations without rotating the text itself?

The Anchor key defines two coordinate with the current transformation matrix active (scaling, rotating, whatever) and from that calculates the angle between these coordinates in the canvas for an un-transformed node.

The code for the Anchor style was inspired by another answer of mine (which could be simplified) to Small text near arrow tips.

The Anchor style probably works best with the circle or the ellipse shape.
The rectangle shape is very nonuniform.

Of course, you can define styles like Below Left/.style={Anchor=45} if you want to use directions for the current transformation matrix.


The code uses \pgfcoordinate which is quick version of \pgfnode for a coordinate. Instead of the \pgfcoordinates we could have written

\path  (0,0) coordinate (qrr@origin)
      (#1:1) coordinate (qrr@direct);

The matrix transformation is then reset (so that we are back in coordinate system that has the same orientation as our canvas in which we place the un-transformed node) with \pgftransformreset.

The macro \pgfmathanglebetweenpoints is not documented in the PGF manual. It is defined in pgfmathcalc.code.tex after a block that warns

% *** The following commands DO NOT WORK without the rest of PGF ***
%
% (a dumping ground for stuff that doesn't really belong anywhere else)

The instruction for \pgfmathanglebetweenpoints read

% \pgfmathanglebetweenpoints
%
% Define \pgfmathresult as the angle between points #1 and #2
% Should get the quadrants right as well.

In the linked answer of mine I did practically the same as that macro but in a manual manner (and maybe not as precise).

The TeX group is necessary so that \pgftransformreset doesn’t affect the actual placement of the node. The \pgfmath@smuggleone (or its @-less version \pgfmathsmuggle) is then used to “smuggle” \pgfmathresult out of the group. The \pgfmath@smuggleone macro is used very often in PGF math. It’s definition in pgfmathutil.code.tex is

% \pgfmath@smuggleone
%
% Smuggle a macro outside a group.
%
% Changed by TT: Speedup by insisting, that smuggleone is directly
% followed by \endgroup
%
\def\pgfmath@smuggleone#1\endgroup{%
  \expandafter\endgroup\expandafter\def\expandafter#1\expandafter{#1}}  

\let\pgfmathsmuggle=\pgfmath@smuggleone

The advance over \globaling it is that it only affects one group and not all.

Code

\documentclass[margin=.5cm]{standalone}
\usepackage{tikz}
\tikzset{
  Anchor/.code=%
    \begingroup
      \pgfcoordinate{qrr@origin}{\pgfpointorigin}%
      \pgfcoordinate{qrr@direct}{\pgfpointpolarxy{#1}{1}}%
      \pgftransformreset
      \pgfmathanglebetweenpoints{\pgfpointanchor{qrr@origin}{center}}{\pgfpointanchor{qrr@direct}{center}}%
      \pgfmathsmuggle\pgfmathresult
    \endgroup
    \tikzset{anchor/.expanded=\pgfmathresult}%
}
\newcommand{\myDraw}[2]{% \myDraw{rotation angle}{scale factor}
\begin{minipage}[t]{2.5cm}
\centering \footnotesize $\theta=#1^{\circ}$, $k=#2$ \medskip\\
  \begin{tikzpicture}[rotate=#1,scale=#2]
    \draw (0,1) -- (0,0) node[Anchor=45] {$O$} -- (1,0) node[midway,Anchor=90] {$1$};
  \end{tikzpicture}
\end{minipage}}

\begin{document}
\myDraw{0}{0.5}
\myDraw{45}{0.7}
\myDraw{90}{1}
\myDraw{135}{1.3}
\myDraw{180}{1.5}
\end{document}

Output

enter image description here


I do not know if this will satisfy you, the question is not very precise. I added the library calc to determine the position of the text. The texts "O" is then positioned relative to the origin, same for "I".

\documentclass[margin=.5cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\myDraw}[2]{% \myDraw{rotation angle}{scale factor}
\begin{minipage}[t]{2.5cm}
\centering \footnotesize $\theta=#1^{\circ}$, $k=#2$ \medskip\\
  \begin{tikzpicture}[rotate=#1,scale=#2]
    \draw (0,1) -- (0,0) coordinate (o) -- (1,0) node[midway,name=i] {$1$};
    \node (O) at ($(o)+(-0.5em,-0.5em)$) {$O$};
    \node (I) at ($(i)+(0,-0.5em)$) {$1$};
  \end{tikzpicture}
\end{minipage}}

\begin{document}
\myDraw{0}{0.5}
\myDraw{45}{0.7}
\myDraw{90}{1}
\myDraw{135}{1.3}
\myDraw{180}{1.5}
\end{document}

enter image description here

another solution

Here's another solution, I use here the intersection between a line and a node (insensitive to scale) to position the text "O", the text "1" it is positioned at the intersection of the line from "O" and "i".

\documentclass[margin=.5cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}

\newcommand{\myDraw}[2]{% \myDraw{rotation angle}{scale factor}
\begin{minipage}[t]{2.5cm}
\centering \footnotesize $\theta=#1^{\circ}$, $k=#2$ \medskip\\
  \begin{tikzpicture}[rotate=#1,scale=#2]
    \draw (0,1) -- (0,0) coordinate (o) -- (1,0) coordinate[midway,name=i];
\node[circle,minimum size=2em](circle) at (o){};
\path(o) -- (-2,-2)coordinate(b);
\path (intersection of o--b and circle) coordinate (oo)node{O};
\path (oo) -| (i) node[pos=0.5]{1};
  \end{tikzpicture}
\end{minipage}}

\begin{document}
\myDraw{0}{0.5}
\myDraw{45}{0.7}
\myDraw{90}{1}
\myDraw{135}{1.3}
\myDraw{180}{1.5}
\end{document}

there is a problem with 180 °!enter image description here


I've eventually came up with a solution to my problem:

\documentclass[margin=.5cm]{standalone}
\usepackage{tikz}

\newcommand{\myDraw}[2]{% \myDraw{rotation angle}{scale factor}
\begin{minipage}[t]{2.5cm}
\centering \footnotesize $\theta=#1^{\circ}$, $k=#2$ \medskip\\
  \begin{tikzpicture}[rotate=#1,scale=#2]
    \draw (0,1) -- (0,0) coordinate (O) -- (1,0) coordinate[midway] (I);
    \begin{scope}[scale=1/#2]
      \draw (O) ++ (-0.25,-0.25) node {$O$};
      \draw (I) ++ (0,-0.25) node {$1$};
    \end{scope}
  \end{tikzpicture}
\end{minipage}}

\begin{document}
\myDraw{0}{0.5}
\myDraw{45}{0.7}
\myDraw{90}{1}
\myDraw{135}{1.3}
\myDraw{180}{1.5}
\end{document}

Result

Among the things I've learned, I can name a point inside a path using coordinate like this:

\draw (0,1) -- (0,0) coordinate (O);

I can also name a node with the keyword name= so I still can use some convenient options like midway or pos=:

\draw (0,0) -- (1,0) node[midway,name=I] {};

But thanks to a comment of Qrrbrbirlbel below, I know now that I can simply use the previous options with coordinate:

\draw (0,0) -- (1,0) coordinate[midway] (I);

Once I've done that, I need to manually position my labels and apply the inverse scale factor:

\begin{scope}[scale=1/#2]
  \draw (O) ++ (-0.25,-0.25) node {$O$};
  \draw (I) ++ (0,-0.25) node {$1$};
\end{scope}

So two issues remain:

  • The scale factor must be passed as an argument to my macro.
  • I need to manually position my labels which means that I can't use convenient anchors like below left).