应该有一种简单的方法可以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}
这得出
你的例子就是
\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}