![“命令后附加”和“插入路径”的问题](https://linux22.com/image/249761/%E2%80%9C%E5%91%BD%E4%BB%A4%E5%90%8E%E9%99%84%E5%8A%A0%E2%80%9D%E5%92%8C%E2%80%9C%E6%8F%92%E5%85%A5%E8%B7%AF%E5%BE%84%E2%80%9D%E7%9A%84%E9%97%AE%E9%A2%98.png)
我有一个例子来解释我的问题,但是如果代码编译并且我得到了一个好的结果,我不明白为什么!
这个想法是像这样分割一个圆节点问题。我想用两种颜色填充节点。
不可能使用相同的代码,但也许我错了。
1)首先使用insert path
,我认为我不能使用,\tikzlastnode
因为这个宏没有定义。\pgf@node@name
似乎只为多部分节点定义。
2) 我尝试使用,append after command
但代码很奇怪。我需要使用带有背景层的范围。但是
\node[ circle,
draw=blue,
text=white,
font=\bfseries,
append after command={
\pgfextra{%
\pgfpointdiff{\pgfpointanchor{\tikzlastnode}{center}}%
{\pgfpointanchor{\tikzlastnode}{east}}%
\pgfmathsetmacro\insiderad{\pgf@x}
\begin{scope}[on background layer]
\fill[orange] (\tikzlastnode.center)
([xshift=\pgflinewidth]\tikzlastnode.west) arc
(180:360:\insiderad-\pgflinewidth);
\fill[red] (\tikzlastnode.center)
([xshift=-\pgflinewidth]\tikzlastnode.east) arc
(0:180:\insiderad-\pgflinewidth);
\end{scope}
}
},text opacity=1] (last name) {big label};
给出
如果我删除范围环境,同样的代码
\fill[orange] (\tikzlastnode.center)
([xshift=\pgflinewidth]\tikzlastnode.west) arc
(180:360:\insiderad-\pgflinewidth);
\fill[red] (\tikzlastnode.center)
([xshift=-\pgflinewidth]\tikzlastnode.east) arc
(0:180:\insiderad-\pgflinewidth);
也会产生不好的结果:
唯一正确的代码似乎是:
\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds,calc}
\begin{document}
\makeatletter
\begin{tikzpicture}[line width=3mm]
\node[ circle,
draw=blue,
text=white,
font=\bfseries,
append after command={
\pgfextra{%
\pgfpointdiff{\pgfpointanchor{\tikzlastnode}{center}}%
{\pgfpointanchor{\tikzlastnode}{east}}%
\pgfmathsetmacro\insiderad{\pgf@x}
\fill[orange] (\tikzlastnode.center)
([xshift=\pgflinewidth]\tikzlastnode.west) arc
(180:360:\insiderad-\pgflinewidth);
\begin{scope}[on background layer]
\fill[red] (\tikzlastnode.center)
([xshift=-\pgflinewidth]\tikzlastnode.east) arc
(0:180:\insiderad-\pgflinewidth);
\end{scope}
}
},text opacity=1] (last name) {big label};
\end{tikzpicture}
\end{document}
我得到:
\pgf@node@name
我的问题是为什么我需要像这样使用范围。第二个问题是想知道除了和 之外 是否有其他方法可以获取最后一个节点的名称\tikzlastnode
。
也许有人知道另一种方法来获得相同的结果。
评论 :
在链接(上面给出的多部分节点)中,我最后意识到我可以删除环境,scope
但这对我来说是一个惊喜。似乎文本被放置在形状构造的末尾。
答案1
导致此处出现奇怪行为的原因是您正在嵌套路径构造。我确信您知道,当 TikZ 构造路径时,它会以稍微特殊的方式处理节点。它们在遇到时进行处理(因为稍后需要有关它们的信息),但直到路径构造完成后才会放置它们。为此,TikZ 将节点存储在一个框中,\tikz@figbox
直到需要放置它们为止。
在处理完节点命令后,键append after command
会在当前路径中多保留一点。需要注意的是,这是前实际节点已放置。这是您想要的,因为您希望将两个半圆放置在节点后面。但是,TikZ 期望的是append after command
当前路径的扩展,而不是全新的路径构造!因此它不会做任何特殊的事情来保护当前路径免受您在代码中执行的任何操作的影响append after command
。在这种情况下,您要做的是创建一个全新的路径!事实上,您创建了两个。
正是这两个节点导致了当前的问题,但我可以想象,即使只有一个节点也会有问题。问题在于节点框\tikz@figbox
正在第一条路径内使用:TikZ 认为父路径中的节点实际上是第一条子路径上的节点。它们在那里被使用,然后该框被清除,第二条子路径被绘制,因此在上面节点的。
补救措施是保护节点框不受子路径的影响。查看 TikZ 代码,还有其他需要执行此操作的地方:预操作和后操作。那里的代码是:
\def\tikz@extra@preaction#1{%
{%
\pgfsys@beginscope%
\setbox\tikz@figbox=\box\pgfutil@voidb@x%
\path[#1];% do extra path
\pgfsyssoftpath@setcurrentpath\tikz@actions@path% restore
\tikz@restorepathsize%
\pgfsys@endscope%
}%
}
由于您正在处理节点而不是路径,因此您可能不需要担心实际路径或范围的任何细节(尽管将它们放入更复杂的示例中可能是最安全的)。您实际上需要的只是分组和声明\tikz@figbox
。因此,以下内容有效:
\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usepackage{trace-pgfkeys}
\usetikzlibrary{shapes,backgrounds,calc}
\begin{document}
\makeatletter
\begin{tikzpicture}[line width=3mm]
\node[ circle,
draw=blue,
text=white,
font=\bfseries,
append after command={
\pgfextra{%
\pgfpointdiff{\pgfpointanchor{\tikzlastnode}{center}}%
{\pgfpointanchor{\tikzlastnode}{east}}%
\pgfmathsetmacro\insiderad{\pgf@x}
{
\setbox\tikz@figbox=\box\pgfutil@voidb@x
\fill[orange] (\tikzlastnode.center)
([xshift=\pgflinewidth]\tikzlastnode.west) arc
(180:360:\insiderad-\pgflinewidth);
\fill[red] (\tikzlastnode.center)
([xshift=-\pgflinewidth]\tikzlastnode.east) arc
(0:180:\insiderad-\pgflinewidth);
}
}
},text opacity=1] {big label};
\end{tikzpicture}
\end{document}
结果:
答案2
关于用法的一个特殊细节append after command
是它必须位于路径构造命令中。换句话说,节点必须中断路径构造,以便无论何时声明它,路径构造都可以继续。但是你在节点命令中使用它,因此事情变得很奇怪。
您可以将节点放在路径命令中,而半径的计算可以通过 let 操作完成。我用浅蓝色填充了背景,并将半填充的节点放在其上方。我仍然不明白如何用不同的颜色填充另一半。这很困难,因为颜色是由 决定的,\path[fill=red]
我不知道如何在路径命令中更改。另一个选择是转到较低级别并使用\pgfpositionnodelater
命令类型来设置整个节点创建过程。
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds,calc}
\begin{document}
\begin{tikzpicture}
\begin{scope}
\clip (0,0) circle (2.65cm);
\fill[blue!25] (-5cm,-5cm) rectangle (5cm,5cm);
\path[fill=red] node[circle,
line width=3mm,
minimum height=5cm,
draw=blue,
text=white,
font=\bfseries,
append after command={
let \p1=(a.east),\p2=(a.center),\n1={veclen(\x1-\x2,0)}
in (a.east) arc (0:180:\n1) -- cycle
}
] at (0,0) (a) {\huge big label};
\end{scope}
\end{tikzpicture}
\end{document}
虽然它不太容易移植,但通过定义一种新的风格,它或许能够浮动。