我一直在玩[reverseclip]如何在 TikZ 中反转“剪辑”选择?。效果很好。当您应用 [reverseclip] 时,它似乎会向您的路径添加另一部分——当前页面的顺时针遍历。但是,我无法理解如何确定多部分路径的内部。例如:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[remember picture,overlay]
% A path that follows the edges of the current page, CW
\tikzstyle{reverseclip}=[insert path={(current page.north east) --
(current page.south east) --
(current page.south west) --
(current page.north west) --
(current page.north east)}
]
\coordinate (A) at (0,0);
\coordinate (B) at (1,0);
\coordinate (C) at (1,1);
\begin{pgfinterruptboundingbox}
\path [clip] (A) -- (B) -- (C) [reverseclip]; % good, CCW
% \path [clip] (C) -- (B) -- (A) [reverseclip]; % bad, CW
\end{pgfinterruptboundingbox}
\fill[red!30] (A) circle (3cm);
%\fill[red!30,even odd rule] (A) circle (3cm); % does not make bad good
\end{tikzpicture}
\end{document}
因此,如果我的路径方向是逆时针,我只能获得所需的反向裁剪。当我将方向设为顺时针时,所有内容都会被不合需要地填充。
在文档第 15.4.2 节“图形参数:内部规则”中,我了解了非零和奇偶规则。我通过想象以 CW 方式绘制的圆圈来合理化这种行为。然后,第一个剪辑路径是 CCW,一切都应该正常工作。使用非零规则,CW 剪辑路径不会剪辑任何东西的原因就说得通了。但是,我尝试指定奇偶规则,期望这会使结果与剪辑路径的方向无关。我的期望错了。
看来内部规则并没有按照我理解的方式应用。
- 裁剪(反向)时,如何确定内部区域?
- 如何逆转通过 \pgfsyssoftpath@getcurrentpath{\mypath} 保存的路径?
- 除了定义 [reverseclipCW] 和 [reverseclipCCW] 之外,有没有办法使 reverseclip 概念对于路径的方向更加稳健?
- 基本形状(圆形、矩形等)的方向是什么?顺时针?
答案1
1- 如何使用nonzero rule
和even odd rule
路径
当前规则(nonzero rule
或even odd rule
)按操作逐个应用,并按路径逐个应用。
如下图所示:
- 在左栏中,所有圆(内圆和外圆)都是逆时针(CCW=逆时针),
- 在右栏中,外圆为逆时针和内圈是 CW(CW=顺时针),
- 在第一行,两条路用于绘制每对圆圈,
- 在第二行和第三行,一条路径用于绘制每对圆圈,
- 在第一行和第二行,填充使用
nonzero rule
(隐式)。 - 在第三行,填充使用
even odd rule
。
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[every node/.style={align=flush left,font=\bfseries}]
\node at (0,3){Outer circle=CCW\\Inner circle=CCW};
\node at (4.5,3){Outer circle=CCW\\Inner circle=CW};
\begin{scope}[yshift=0mm,
every path/.style={draw=black,fill=cyan}]
\path (0,0) ++(0:2cm) arc (0:360:2cm);
\path (0,0) ++(0:1.8cm) arc (0:360:1.4cm);
\path (4.5,0) ++(0:2cm) arc (0:360:2cm);
\path (4.5,0) ++(0:1.8cm) arc (360:0:1.4cm);
\node[right] at (7,0) {Each circle=one path};
\end{scope}
\begin{scope}[yshift=-4.5cm,
every path/.style={draw=black,fill=orange}]
\path (0,0) ++(0:2cm) arc (0:360:2cm)
(0,0) ++(0:1.8cm) arc (0:360:1.4cm);
\path (4.5,0) ++(0:2cm) arc (0:360:2cm)
(4.5,0) ++(0:1.8cm) arc (360:0:1.4cm);
\node[right] at (7,0)
{Outer and inner circles=single path\\nonzero rule};
\end{scope}
\begin{scope}[yshift=-9cm,
even odd rule,every path/.style={draw=black,fill=lime}]
\path (0,0) ++(0:2cm) arc (0:360:2cm)
(0,0) ++(0:1.8cm) arc (0:360:1.4cm);
\path (4.5,0) ++(0:2cm) arc (0:360:2cm)
(4.5,0) ++(0:1.8cm) arc (360:0:1.4cm);
\node[right] at (7,0)
{Outer and inner circles=single path\\even odd rule};
\end{scope}
\end{tikzpicture}
\end{document}
2-如何nonzero rule
使用even odd rule
剪裁路径
不能even odd rule
直接应用于剪切路径(这是一个错误)。
在以下示例中,每行均显示一个填充的矩形。每个矩形均由单个路径中的四个圆圈剪切。第一行使用nonzero rule
(隐式),第二行使用范围应用于even odd rule
剪切路径,第三行使用 Andrew Stacey 建议的新选项clip even odd rule
:
\tikzset{clip even odd rule/.code={\pgfseteorule}} % Credit to Andrew Stacey
\documentclass{standalone}
\usepackage{tikz}
\tikzset{clip even odd rule/.code={\pgfseteorule}} % Credit to Andrew Stacey
\begin{document}
\begin{tikzpicture}[every node/.style={align=flush left,font=\bfseries}]
\node at (2.25,3) {All circles in a single clipping path};
\node at (0,2){Outer circle=CCW\\Inner circle=CCW};
\node at (4.5,2){Outer circle=CCW\\Inner circle=CW};
\begin{scope}[yshift=0mm]
\node[right] at (7,0) {clipping path with nonzero rule};
\clip
(0,0) circle (2cm)
(0,0) ++(0:1.8cm) arc (0:360:1.4cm)
(4.5,0) circle (2cm)
(4.5,0) ++(0:1.8cm) arc (360:0:1.4cm);
\draw[fill=red] (-2,-1) rectangle (7,1);
\end{scope}
\begin{scope}[yshift=-4.5cm,even odd rule]
\node[right] at (7,0) {clipping path with even odd rule\\(via scope)};
\clip
(0,0) circle(2cm)
(0,0) ++(0:1.8cm) arc (0:360:1.4cm)
(4.5,0) circle(2cm)
(4.5,0) ++(0:1.8cm) arc (360:0:1.4cm);
\draw[fill=orange] (-2,-1) rectangle (7,1);
\end{scope}
\begin{scope}[yshift=-9cm]
\node[right] at (7,0)
{clipping path with even odd rule\\(via new \texttt{clip even odd rule} option)};
\clip[clip even odd rule]
(0,0) circle(2cm)
(0,0) ++(0:1.8cm) arc (0:360:1.4cm)
(4.5,0) circle(2cm)
(4.5,0) ++(0:1.8cm) arc (360:0:1.4cm);
\draw[fill=lime] (-2,-1) rectangle (7,1);
\end{scope}
\end{tikzpicture}
\end{document}
关于 CCW 和 CW 的注释:
在路径中:
- A
circle
(或ellipse
)操作始终是 CCW。 rectangle
根据提供的角,操作可以是 CCW 或 CW :(a) rectangle (b)
相当于(a) -| (b) |- (a)
。