这是有没有办法在路径的“内部”或“外部”绘制 TikZ 线?
由于另一个问题已经很老了,我想问一下,TikZ 是否同时能够在路径内部、路径上或路径外部绘制笔触,就像这张图一样?
这是使用以下代码生成的,用于\pgflinewidth
更改实际路径。但此解决方案不适用于任意形状,也不适用于节点,此外,缩放图片时它会失效。
\documentclass[border=5mm,tikz]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[
every node/.style = {below=5mm, text=black, font=\small},
% scale = 1.5,
]
% path
\draw [red] (0,0) rectangle +(2,2)
+(1,0) node {actual path};
% stroke on path
\draw [line width = 4mm] (3,0) rectangle +(2,2);
\draw [red] (3,0) rectangle +(2,2)
+(1,0) node {stroke on path};
% stroke inside path
\draw [line width = 4mm]
($(6,0)+(\pgflinewidth/2,\pgflinewidth/2)$) rectangle
+($(2,2)-(\pgflinewidth,\pgflinewidth)$);
\draw [red] (6,0) rectangle +(2,2)
+(1,0) node {stroke inside path};
% stroke outsie path
\draw [line width = 4mm]
($(9,0)-(\pgflinewidth/2,\pgflinewidth/2)$) rectangle
+($(2,2)+(\pgflinewidth,\pgflinewidth)$);
\draw [red] (9,0) rectangle +(2,2)
+(1,0) node {stroke outside path};
\end{tikzpicture}
\end{document}
实际上我需要它来绘制一行节点,其中一些节点被填充,一些节点被绘制,但总高度应该相等,并且它们不应该重叠。它应该是这样的不是看起来像:
相反,“State B” 和 “State C” 的笔画应该位于路径内部。(postaction
仅用于演示。)
代码:
\begin{tikzpicture}[
every node/.style = {
inner sep=0pt, outer sep=0pt, postaction = {draw, red, thin},
minimum height = 8mm, anchor = south west, font=\small
},
a/.style = {fill = gray},
b/.style = {draw, line width = 2mm},
c/.style = {draw, line width = 2mm, shape = signal },
]
\node at (0,0) [minimum width = 20mm, a] {State A};
\node at (2,0) [minimum width = 20mm, b] {State B};
\node at (4,0) [minimum width = 30mm, a] {State A};
\node at (7,0) [minimum width = 30mm, c] {State C};
\draw [->] (0,-0.5) -- +(10.5,0);
\foreach \x in {0,0.5,...,10}
\draw (\x,-0.6) -- (\x,-0.4);
\end{tikzpicture}
答案1
想出一个绘制路径外侧的装饰是比较容易的。原则上,可以反转路径以绘制内部的曲线,但这会产生一些无法预料的后果。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,decorations}
\pgfdeclaredecoration{stroke outside path}{initial}{%
\state{initial}[width=\pgfdecoratedinputsegmentlength/100,next state=iterate]
{
\pgfpathmoveto{\pgfqpoint{0pt}{.5\pgflinewidth}}
}%
\state{iterate}[width=\pgfdecoratedinputsegmentlength/100]
{
\pgfpathlineto{\pgfqpoint{.5\pgflinewidth}{.5\pgflinewidth}}
}%
\state{final}{%
\pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgflinewidth}{.5\pgflinewidth}}{\pgfpointdecoratedpathlast}}
}%
}%
\begin{document}
\begin{tikzpicture}[
every node/.style = {below=5mm, text=black, font=\small},
% scale = 1.5,
]
% path
\draw [red] (0,0) rectangle +(2,2)
+(1,0) node {actual path};
% stroke on path
\draw [line width = 4mm] (3,0) rectangle +(2,2);
\draw [red] (3,0) rectangle +(2,2)
+(1,0) node {stroke on path};
% stroke inside path
\draw [decoration={reverse path, stroke outside path}, decorate, line width = 4mm] (6,0) rectangle +(2,2);
\draw [red] (6,0) rectangle +(2,2)
+(1,0) node {stroke inside path};
% stroke outsie path
\draw [decoration=stroke outside path, decorate, line width = 4mm] (9,0) rectangle +(2,2);
\draw [red] (9,0) rectangle +(2,2)
+(1,0) node {stroke outside path};
\end{tikzpicture}
\begin{tikzpicture}
\draw [decoration=stroke outside path, decorate, line width = 4mm] (0,0) .. controls (1,-1) and (2,2) .. (3,0);
\draw [red] (0,0) .. controls (1,-1) and (2,2) .. (3,0);
\end{tikzpicture}
\end{document}
答案2
对于此解决方案,您需要加载calc
库。然后,我们将基本上为样式绘制一条线b
,该线附加在设置节点后。如果没有calc
,该线将像您的示例中那样出现,但使用它,我们可以添加或删除\pgflinewidth
。
我还没有测试过,但它应该是可扩展的。
输出
代码
\documentclass[margin=10pt]{standalone}
\usepackage{pgffor}
\usepackage{subcaption}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[
every node/.style = {
inner sep=0pt, outer sep=0pt, postaction = {draw, red, thin},
minimum height = 8mm, anchor = south west, font=\small
},
a/.style = {fill = gray},
b/.style = {append after command={\pgfextra{
\draw[line width=1mm] ($(\tikzlastnode.south west)+(.5\pgflinewidth,.5\pgflinewidth)$) rectangle ($(\tikzlastnode.north east)+(-.5\pgflinewidth,-.5\pgflinewidth)$);
}}},
]
\node at (0,0) [minimum width = 20mm, a] {State A};
\node at (2,0) [minimum width = 20mm, b] {State B};
\node at (4,0) [minimum width = 30mm, a] {State A};
\end{tikzpicture}
\end{document}