具有旋转和缩放功能的倾斜 Tikz 节点

具有旋转和缩放功能的倾斜 Tikz 节点

应该有一种简单的方法可以sloped node沿路径放置。使用sloped效果很好(如黑色文本中所示)。但是,如果应用了,rotate=则文本不再沿着路径(如红色和蓝色示例所示)。如果我使用(如橙色示例所示),则可以获得正确的方向,但如果应用了,transform shape文本就会缩放。scale=

问题:如何定义\MyDraw宏以便可以与rotate 比如scale

  • rotate=即使应用了a,文本仍沿着路径,并且
  • 文本是不是受到的影响scale=

在此处输入图片描述

笔记:

  • 在我的实际使用中,这些绘图都是相同的tikzpicture,我使用scope来应用所需的转换。为了让 MWE 尽可能接近我的实际用例,我scope在下面的 MWE 中使用了 s ,而不是将选项应用于tikzpicture本身。

代码:

\documentclass{article}
\usepackage{tikz}

\newcommand*{\MyDraw}[1]{%
    \draw [ultra thick, -latex] (0,0) -- (1,4) 
        node [midway, above, sloped, align=center] {#1};
}%

\begin{document}
\begin{tikzpicture}
    \MyDraw{not rotated};
\end{tikzpicture}%
% --------------------------------- apply "rotation"
\begin{tikzpicture}
    \begin{scope}[rotate=-25, red]
        \MyDraw{rotated};
    \end{scope}
\end{tikzpicture}%
% --------------------------------- apply "rotation" and "scale"
\begin{tikzpicture}
    \begin{scope}[rotate=-15, scale=1.3, blue]
        \MyDraw{rotated and scaled};
    \end{scope}
\end{tikzpicture}%
% --------------------------------- apply "rotation", "scale" and "transform shape"
\begin{tikzpicture}
    \begin{scope}[rotate=-15, scale=1.5, transform shape, orange]
        \MyDraw{rotated, scaled and \\ ``transform shape"};
    \end{scope}
\end{tikzpicture}
\end{document}

答案1

如果只想将文本放在直线上,一种选择是明确计算角度,以 为前缀\pgftransformreset,然后相应地旋转节点:

\documentclass[tikz]{standalone}

\def\getangle(#1)(#2)#3{%
  \begingroup%
    \pgftransformreset%
    \pgfmathanglebetweenpoints{\pgfpointanchor{#1}{center}}{\pgfpointanchor{#2}{center}}%
    \expandafter\xdef\csname angle#3\endcsname{\pgfmathresult}%
  \endgroup%
}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\getangle(A)(B)a;
\draw (A) -- node [midway,above,rotate=\anglea] {text} (B);
%%
\begin{scope}[xshift=2cm,rotate=30,yscale=1.3,xscale=1.5]
\coordinate (C) at (0,0);
\coordinate (D) at (1,1);
\getangle(C)(D)b;
\draw (C) -- node [midway,above,rotate=\angleb] {text} (D);
\end{scope}
\end{tikzpicture}
\end{document}

这得出

结果为 png

你的例子就是

\documentclass{article}
\usepackage{tikz}

\def\getangle(#1)(#2)#3{%
  \begingroup%
    \pgftransformreset%
    \pgfmathanglebetweenpoints{\pgfpointanchor{#1}{center}}{\pgfpointanchor{#2}{center}}%
    \expandafter\xdef\csname angle#3\endcsname{\pgfmathresult}%
  \endgroup%
}

\newcommand*{\MyDraw}[1]{%
    \coordinate (A) at (0,0);
    \coordinate (B) at (1,4);
    \getangle(A)(B)a
    \draw [ultra thick, -latex] (A) -- (B) 
        node [midway, above, rotate=\anglea, align=center] {#1};
}%

\begin{document}
\begin{tikzpicture}
    \MyDraw{not rotated};
\end{tikzpicture}%
% --------------------------------- apply "rotation"
\begin{tikzpicture}
    \begin{scope}[rotate=-25, red]
        \MyDraw{rotated};
    \end{scope}
\end{tikzpicture}%
% --------------------------------- apply "rotation" and "scale"
\begin{tikzpicture}
    \begin{scope}[rotate=-15, scale=1.3, blue]
        \MyDraw{rotated and scaled};
    \end{scope}
\end{tikzpicture}%
\end{document}

屈服

编译的第二个代码

但这种方法不适用于transform shape

答案2

改用:nodes={rotate=<angle>}transform shape

与仅转换的transform shape通道相比nodes={rotate=<angle>}已选择通过其参数(即rotate=<angle>)到范围之内的所有节点。

将新样式定义myrotate为缩写

\tikzset{
  myrotate/.style={rotate=#1,nodes={rotate=#1}}
}

myrotate=<angle>使用rotate=<angle>

在此处输入图片描述

代码:

\documentclass{article}
\usepackage{tikz}
\tikzset{
  myrotate/.style={rotate=#1,nodes={rotate=#1}}
}

\newcommand*{\MyDraw}[1]{%
    \draw [ultra thick, -latex] (0,0) -- (1,4) 
        node [midway, above, sloped, align=center] {#1};
}%

\begin{document}
\begin{tikzpicture}
    \MyDraw{not rotated};
\end{tikzpicture}%
% --------------------------------- apply "rotation"
\begin{tikzpicture}
    \begin{scope}[myrotate=-25,red]
        \MyDraw{rotated};
    \end{scope}
\end{tikzpicture}%
% --------------------------------- apply "rotation" and "scale"
\begin{tikzpicture}
    \begin{scope}[myrotate=-15,scale=1.3, blue]
        \MyDraw{rotated and scaled};
    \end{scope}
\end{tikzpicture}%
% --------------------------------- apply "rotation", "scale" and "transform shape"
\begin{tikzpicture}
    \begin{scope}[myrotate=-15, scale=1.5, orange]
        \MyDraw{rotated, scaled and \\ ``transform shape"};
    \end{scope}
\end{tikzpicture}
\end{document}

答案3

我曾经为 TikZ 编写过一个线性代数库(主要用于处理复数),但由于现在 TikZ 大量使用 Lua,Lua 已经过时了,所以我停止了它。不过,这里快速窃取了二乘二矩阵的 Givens QR 分解,将变换矩阵分为缩放和旋转,我们只使用旋转部分,省略缩放/倾斜部分。

可以使用相同的想法来取消旋转并保持缩放以回答评论中的问题。如果我有更多时间,我会看看。

\documentclass{article}
\usepackage{tikz}

\newcommand*{\MyDraw}[1]{%
    \draw [ultra thick, -latex] (0,0) -- (1,4) 
        node [midway, above, sloped, align=center,cancel scale] {#1};
}%
\tikzset{cancel scale/.code=\pgfmathcancelscale}

\makeatletter
\def\pgfmathcancelscale{%
  \pgfgettransformentries{\my@a}{\my@b}{\my@c}{\my@d}{\my@xi}{\my@yi}%
  \pgfmathsetmacro\my@cos{\my@a/veclen(\my@a,\my@c)}%
  \pgfmathsetmacro\my@sin{-\my@c/veclen(\my@a,\my@c)}%
  \pgfsettransformentries{\my@cos}{\my@sin}{-\my@sin}{\my@cos}{\my@xi}{\my@yi}%
}
\makeatother

\begin{document}

\begin{tikzpicture}
    \begin{scope}[rotate=-15, scale=1.5, transform shape, orange]
        \MyDraw{rotated, scaled and \\ ``transform shape"};
            \begin{scope}[rotate=40, scale=0.2, shift={(10cm,-5cm)},transform shape, blue]
            \MyDraw{rotated, scaled and \\ ``transform shape"};
            \end{scope}
    \end{scope}
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案4

该解决方案是对乔纳森的回答。通过调用选项Sloped而不是sloped.可以轻松使用。transform shape

\documentclass[tikz]{standalone}
\usepackage{tikz}

\makeatletter
\tikzset{
Sloped/.code = {
\iftikz@fullytransformed% tikz.code.tex
    \tikzset{sloped}
\else
    \pgfgettransformentries{\mya}{\myb}{\myc}{\myd}{\mys}{\myt}%
    \tikzset{sloped, rotate = {atan2(\myb,\mya)}}%
\fi
}
}
\makeatother

\newcommand*{\MyDraw}[1]{
\coordinate (A) at (0,0);
\coordinate (B) at (60:4);
\draw [ultra thick, -latex] (A) -- (B) node [midway, above, Sloped, align=center] {#1};% Sloped instead of sloped
}

\begin{document}
\foreach \i in {0,10,...,360}{% test a list of angles
\begin{tikzpicture}
\path (-7.5,-7.5) rectangle (7.5,7.5);
\MyDraw{not rotated};
% --------------------------------- apply "rotation"
\begin{scope}[rotate=15+\i, red]
\MyDraw{rotated};
\end{scope}
% --------------------------------- apply "rotation" and "scale"
\begin{scope}[rotate=30+\i, scale=1.3, blue]
\MyDraw{rotated and scaled};
\end{scope}
% --------------------------------- apply "rotation", "scale" and "transform shape"
\begin{scope}[rotate=45+\i, scale=1.5, transform shape, orange]
\MyDraw{rotated, scaled and \\ ``transform shape"};
\end{scope}
\end{tikzpicture}
}
\end{document}

在此处输入图片描述

相关内容