提问于:
浏览数:
1748
## 编译环境
操作系统
* [x] Windows 10
* [ ] macOS
* [ ] Linux
`若需勾选,请把[ ]改成[x]`
Tex发行版
* [x] TexLive 2020
* [ ] MikTeX `版本号`
* [ ] CTeX
`若需勾选,请把[ ]改成[x]`
## 我的问题
`rotate=90` 旋转选项和 `below=1em` 相对位置选项在添加 `positioning` 程序库前后效果不一。希望效果是在 `positioning` 程序库的加持下,仍能保持图 1 的效果。
```tex
\documentclass[tikz]{standalone}
% \usetikzlibrary{positioning}
\tikzset{rotatetext/.style={
rotate=90,below=1em,minimum width=3cm,draw=#1,fill=#1!30
}}
\begin{document}
\begin{tikzpicture}
\node[rotatetext=red] (a) {aaaaaaaaaa};
\node[rotatetext=blue] (b) at (a.south) {bbbbbbbbbb};
\node[rotatetext=green] (c) at (b.south) {cccccccccc};
\end{tikzpicture}
\end{document}
```
![正确](https://wenda.latexstudio.net/data/attach/200607/DLh5avZx.png "正确")
添加 `positioning` 程序库后,3个 `node` 错位。
```tex
\documentclass[tikz]{standalone}
\usetikzlibrary{positioning}
\tikzset{rotatetext/.style={
rotate=90,below=1em,minimum width=3cm,draw=#1,fill=#1!30
}}
\begin{document}
\begin{tikzpicture}
\node[rotatetext=red] (a) {aaaaaaaaaa};
\node[rotatetext=blue] (b) at (a.south) {bbbbbbbbbb};
\node[rotatetext=green] (c) at (b.south) {cccccccccc};
\end{tikzpicture}
\end{document}
```
![错位](https://wenda.latexstudio.net/data/attach/200607/jaGaHXLk.png "错位")
不为 `below` 选项指定距离后,`node` 的错位消失
```tex
\documentclass[tikz]{standalone}
\usetikzlibrary{positioning}
\tikzset{rotatetext/.style={
rotate=90,below,minimum width=3cm,draw=#1,fill=#1!30
}}
\begin{document}
\begin{tikzpicture}
\node[rotatetext=red] (a) {aaaaaaaaaa};
\node[rotatetext=blue] (b) at (a.south) {bbbbbbbbbb};
\node[rotatetext=green] (c) at (b.south) {cccccccccc};
\end{tikzpicture}
\end{document}
```
![无间距](https://wenda.latexstudio.net/data/attach/200607/7ExzgtEl.png "无间距")
2 回答
0
试了一下
```
\tikzset{rotatetext/.style={
rotate=90,right=1em,anchor=north,minimum width=3cm,draw=#1,fill=#1!30
}}
```
效果是
![](https://wenda.latexstudio.net/data/attach/200608/iTETrmGS.png)
在`\node[rotate=90,below=1em] (b) at (a.south) {bbbbbbbbbb};`中,有两个变换,一个是`rotate=90`代表的旋转,一个是`below=1em`代表的平移,这个平移等价于
```
\pgftransformshift{\pgfqpoint{0pt}{-1em}}
```
表面上看,旋转在平移之前,但由于某个“一两句话说不完的原因”,导致这个平移先起作用,旋转后起作用。
------------
我说说那个“一两句话说不完的原因”吧,仅仅是个人理解,如果不对请指正。
在文件《tikzlibrarypositioning.code.tex》(目前的3.1.5b版本)的开头有这样的代码:
```
\pgfutil@g@addto@macro\tikz@node@reset@hook{\tikz@addtransform{\tikz@lib@pos@call}\let\tikz@lib@pos@call=\relax}
```
这里全局地重定义了命令`\tikz@node@reset@hook`,然后再看这个命令用在了什么地方。在文件《tikz.code.tex》中搜索这个命令,发现在`\tikz@fig ode`,或者说在`\tikz@normal@fig`中用了这个命令,这是解析 node 语句的命令。
执行`\tikz@node@reset@hook`的作用是把`\tikz@lib@pos@call`添加到`\tikz@transform`中。
`\tikz@fig ode`有这样的执行次序:
1.`\tikz@node@reset@hook`
2.`\tikzset{every node/.try}`
3.`\tikz@fig@scan@options`,这是执行 node 的选项,选项`rotate=90`会把旋转命令添加到`\tikz@transform`中,选项`below=1em`会重定义`\tikz@lib@pos@call`,使之保存平移命令。
所以,当执行`\tikz@transform`时,`\tikz@lib@pos@call`在前(平移命令在前),旋转命令在后。
费解的地方在于`\tikz@node@reset@hook`的用法。
文件《tikzlibrarypositioning.code.tex》只有119行,比较简短。
-
非常感谢! – zhaochongbin 2020-06-08 20:01 回复
0
`positioning`库并没有通过`\tikz@addtransform`把平移操作加入`\tikz@transform`中,即平移操作是立即执行的,`below`和`rotate`在一起时总是`below`先执行,若使用内建的命令,变换操作都是存储到`\tikz@transform`,最后按照加入的顺序运行。
详细的原因见[https://tex.stackexchange.com/questions/548329/tikz-execution-order-of-transformation](https://tex.stackexchange.com/questions/548329/tikz-execution-order-of-transformation)
你的回答
请登录后回答
你的回答将会帮助更多人,请务必认真回答问题。