首先,免责声明:我不敢相信我是第一个问这个问题的人,所以我可能错过了一个显而易见的答案。
我们可以使用锚点来定位节点。但定位后,节点的默认锚点将回到中心。
有没有办法在引用节点时设置其默认锚点(例如在计算中或在路径中)?
以手册第 17.5.2 节的情况为例,但使用 calc 而不是路径:
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=center}]
\node (x) {x};
\node at ($(x)+(2,0)$) (y) {y};
\node at ($(x)+(4,0)$) (z) {z};
\path[draw,red] (x) -- (y) -- (z);
\end{scope}
\end{tikzpicture}
对齐被破坏了,因此根据手册我将锚点更改为mid
:
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=mid}]
\node (x) {x};
\node at ($(x)+(2,0)$) (y) {y};
\node at ($(x)+(4,0)$) (z) {z};
\path[draw,red] (x) -- (y) -- (z);
%\path[draw,cyan] (x.mid) -- (y.mid) -- (z.mid);
\end{scope}
\end{tikzpicture}
哦哦,现在路径不再是直的了。至少对齐是正确的,因为center
x 的 也是它的mid
,但如果我们改用base
:
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=base}]
\node (x) {x};
\node at ($(x)+(2,0)$) (y) {y};
\node at ($(x)+(4,0)$) (z) {z};
\path[draw,red] (x) -- (y) -- (z);
%\path[draw,cyan] (x.base) -- (y.base) -- (z.base);
\end{scope}
\end{tikzpicture}
现在对齐和路径都被破坏了。
为了修复此问题,我们需要在后续命令中将锚点添加到节点的每个引用中:
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=base}]
\node (x) {x};
\node at ($(x.base)+(2,0)$) (y) {y};
\node at ($(x.base)+(4,0)$) (z) {z};
\path[draw,red] (x.base) -- (y.base) -- (z.base);
%\path[draw,cyan] (x.base) -- (y.base) -- (z.base);
\end{scope}
\end{tikzpicture}
因此,问题是:我们真的必须这样做吗?或者我们可以告诉节点“记住”它们的锚点是mid
, 或base
,或者其他什么?
基本上,我想要一种方法来仅在一个地方修改第三个片段并获取第四个输出。
(作为奖励,如果这个“记住”的锚点可以像默认锚点一样运行,并遵循内外分离,那就更好了。但这似乎是完全是另一个问题。
梅威瑟:
\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=center}]
\node (x) {x};
\node at ($(x)+(2,0)$) (y) {y};
\node at ($(x)+(4,0)$) (z) {z};
\path[draw,red] (x) -- (y) -- (z);
\end{scope}
\end{tikzpicture}
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=mid}]
\node (x) {x};
\node at ($(x)+(2,0)$) (y) {y};
\node at ($(x)+(4,0)$) (z) {z};
\path[draw,red] (x) -- (y) -- (z);
%\path[draw,cyan] (x.mid) -- (y.mid) -- (z.mid);
\end{scope}
\end{tikzpicture}
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=base}]
\node (x) {x};
\node at ($(x)+(2,0)$) (y) {y};
\node at ($(x)+(4,0)$) (z) {z};
\path[draw,red] (x) -- (y) -- (z);
%\path[draw,cyan] (x.base) -- (y.base) -- (z.base);
\end{scope}
\end{tikzpicture}
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=base}]
\node (x) {x};
\node at ($(x.base)+(2,0)$) (y) {y};
\node at ($(x.base)+(4,0)$) (z) {z};
\path[draw,red] (x.base) -- (y.base) -- (z.base);
%\path[draw,cyan] (x.base) -- (y.base) -- (z.base);
\end{scope}
\end{tikzpicture}
\end{document}
答案1
我只是提出一些解决方法。它们可能不能解决你的实际问题。但如果你指出为什么它们不起作用,我就会更好地了解你真正想要什么。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
Your MWE
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=center}]
\node (x) {x};
\node at ($(x)+(1,0)$) (y) {y};
\node at ($(x)+(2,0)$) (z) {z};
\path[draw,red] (x) -- (y) -- (z);
\end{scope}
\end{tikzpicture}
\def\cs#1{\texttt{\string#1}}
First workaround: \cs\strut{} or minimum size
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=center}]
\node (x) {x\strut};
\node at ($(x)+(1,0)$) (y) {y\strut};
\node at ($(x)+(2,0)$) (z) {z\strut};
\path[draw,red] (x) -- (y) -- (z);
\end{scope}
\end{tikzpicture}
Second workaround: declare an anchor as a coordinate.
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=base}]
\node (x) {x};
\coordinate (x!!) at (x.base);
\node at ($(x!!)+(1,0)$) (y) {y};
\coordinate (y!!) at (y.base);
\node at ($(x!!)+(2,0)$) (z) {z};
\coordinate (z!!) at (z.base);
\path[draw,red] (x!!) -- (y!!) -- (z!!);
\end{scope}
\end{tikzpicture}
Remember that you can do
\texttt{\cs\coordinate{} (z<) at (z.base west);} and
\texttt{\cs\coordinate{} (z>) at (z.base east);}.
\end{document}
答案2
(基于优秀的建议由 Symbol1)
您可以在所需的精确点处声明一个坐标:
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=base}]
\coordinate (x!!);
\node (x) at (x!!) {x};
\coordinate (y!!) at ($(x!!)+(1,0)$);
\node (y) at (y!!) {y};
\coordinate (z!!) at ($(x!!)+(2,0)$);
\node (z) at (z!!) {x};
\path[draw,red] (x!!) -- (y!!) -- (z!!);
\end{scope}
\end{tikzpicture}
请注意,base
仅出现在范围选项中并且可以随意更改。
如果需要,可以将坐标+节点这两条线组合成一个宏。在这种情况下,您还可以定义相对于固定锚点放置的坐标。
总的来说,它给出了:
\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc,positioning,shapes}
\begin{document}
\newcommand{\pinnode}[4][]{%
% Options, positioning, name, text
\coordinate (#3!!) #2;
\node[#1] at (#3!!) (#3) {#4};
\path[draw=none] (#3!!) -| (#3.east)
coordinate[pos=0.5] (#3>);
\path[draw=none] (#3!!) -| (#3.west)
coordinate[pos=0.5] (#3<);
\path[draw=none] (#3!!) |- (#3.south)
coordinate[pos=0.5] (#3v);
\path[draw=none] (#3!!) |- (#3.north)
coordinate[pos=0.5] (#3^);
}
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=base, inner sep=10pt}]
\pinnode[draw,rectangle]{}{x}{Text of the node};
\begin{scope}[every node/.style={anchor=center,inner sep=1pt,circle,fill=blue},
every path/.style={draw=cyan}]
\draw (x<) -- (x>);
\draw (xv) -- (x^);
\node[red] at (x!!) {};
\node at (x<) {};
\node at (x>) {};
\node at (xv) {};
\node at (x^) {};
\end{scope}
\end{scope}
\end{tikzpicture}
\vspace{1cm}
\begin{tikzpicture}
\begin{scope}[every node/.style={anchor=170, inner sep=5pt}]
\pinnode[draw,shape=ellipse]{}{x}{Text of the node};
\begin{scope}[every node/.style={anchor=center,inner sep=1pt,circle,fill=blue},
every path/.style={draw=cyan}]
\draw (x<) -- (x>);
\draw (xv) -- (x^);
\node[red] at (x!!) {};
\node at (x<) {};
\node at (x>) {};
\node at (xv) {};
\node at (x^) {};
\end{scope}
\end{scope}
\end{tikzpicture}
再次注意,对锚点的唯一引用是在外部范围。