我希望在坐标为 (A)、(B) 和 (C) 的三角形外侧画一条弧来表示反射角。
如果我想在三角形内画圆弧,我可以使用类似
\begin{scope}
\path[clip] (A) -- (B) -- (C) -- cycle;
\draw (B) circle (2mm); % this is the little angle marker
\end{scope}
有没有一个简单的方法排除圆位于三角形内的部分,如下面的伪代码所示?
\begin{scope}
\path[magicalinverseclipcommand] (A) -- (B) -- (C) -- cycle;
\draw (B) circle (2mm); % this is the little angle marker
\end{scope}
编辑:虽然我将上面的代码作为反向剪辑的激励示例,但我更喜欢系统地处理任何封闭路径的通用解决方案,而不仅仅是在三角形中剪辑出一个圆的特定示例中。看着我的问题,我意识到这并不清楚,我会对我的特定问题的最佳解决方案感到满意,但我想知道是否有比目前列出的解决方案更少临时的解决方案。
答案1
您可以做的是向剪切路径添加一个大于当前边界框的矩形,然后使用该矩形进行剪切。Andrew Stacey 建议使用当前页面作为剪切矩形,因为这样可以捕获后面的所有元素。通过pgfinterruptboundingbox
在定义剪切矩形时使用环境,实际大小tikzpicture
不会受到影响。
请注意,为了使用current page
,remember picture,overlay
需要将选项传递给tikzpicture
,并且需要运行两次编译才能正确定位所有元素。此外,这不适用于 documentclass minimal
。
\documentclass{article} % Has to be a proper class, not minimal
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[remember picture,overlay]
% A path that follows the edges of the current page
\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} % To make sure our clipping path does not mess up the placement of the picture
\path [clip] (A) -- (B) -- (C) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\draw[thick] (A) circle (2mm);
\draw[thick] (B) circle (2mm);
\draw[thick] (C) circle (2mm);
\end{tikzpicture}
\end{document}
只是为了证明它适用于一般情况:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[remember picture,overlay]
% A path that follows the edges of the current page
\tikzstyle{reverseclip}=[insert path={(current page.north east) --
(current page.south east) --
(current page.south west) --
(current page.north west) --
(current page.north east)}
]
\draw [step=0.1,red] (0,0) grid (2,2);
\begin{pgfinterruptboundingbox} % To make sure our clipping path does not mess up the placement of the picture
\path [clip,rounded corners] (0,0) -- (.75,0) -- (1.2,.8) -- (2,1) -- (1.4,1) -- (1.2,2) -- (.3,.75) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\draw [step=0.1,thick] (0,0) grid (2,2);
\end{tikzpicture}
\end{document}
答案2
为了避免remember picture
和overlay
,我使用以下方法混合 Jack 溶液和 Altermundus 溶液:大TikZ/PGF(TeX?)可以使用的矩形(编辑:正如 Qrrbrbirlbel 所建议的,我添加了[reset cm]
一个独立于任何尺度变换的解决方案)。
第一个 tikzpicture 显示了两个(inv)剪辑三角形。
第二张 tikzpicture 显示的效果nonzero rule
(even odd rule
不能直接在剪切路径中使用,请参阅下面的注释)。
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\tikzset{invclip/.style={clip,insert path={{[reset cm]
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
}}}}
\begin{tikzpicture}[outer sep=0mm]
\coordinate (A) at (0,0);
\coordinate (B) at (1,0);
\coordinate (C) at (.5,1);
\coordinate (Ap) at (0,1);
\coordinate (Bp) at (1,1);
\coordinate (Cp) at (.5,0);
\begin{scope}
\begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
\path[invclip]
(A) -- (B) -- (C) -- (A)
(Ap) -- (Cp) -- (Bp) -- (Ap);
\end{pgfinterruptboundingbox}
\fill[orange!50] (-1,-1) rectangle (2,2);
\draw (A) circle (2mm); % this is the little angle marker
\draw (B) circle (2mm); % this is the little angle marker
\draw (C) circle (2mm); % this is the little angle marker
\draw (Ap) circle (2mm); % this is the little angle marker
\draw (Bp) circle (2mm); % this is the little angle marker
\draw (Cp) circle (2mm); % this is the little angle marker
\end{scope}
\draw[red] (current bounding box.south west)
rectangle (current bounding box.north east);
\end{tikzpicture}
\begin{tikzpicture}[outer sep=0mm]
\coordinate (A) at (0,0);
\coordinate (B) at (1,0);
\coordinate (C) at (.5,1);
\coordinate (Ap) at (0,1);
\coordinate (Bp) at (1,1);
\coordinate (Cp) at (.5,0);
\begin{scope}
\begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
\path[invclip]
(A) -- (B) -- (C) -- (A)
(Ap) -- (Bp) -- (Cp) -- (Ap);
\end{pgfinterruptboundingbox}
\fill[orange!50] (-1,-1) rectangle (2,2);
\draw (A) circle (2mm); % this is the little angle marker
\draw (B) circle (2mm); % this is the little angle marker
\draw (C) circle (2mm); % this is the little angle marker
\draw (Ap) circle (2mm); % this is the little angle marker
\draw (Bp) circle (2mm); % this is the little angle marker
\draw (Cp) circle (2mm); % this is the little angle marker
\end{scope}
\draw[red] (current bounding box.south west)
rectangle (current bounding box.north east);
\end{tikzpicture}
\end{document}
关于规则和剪辑的注意事项:
在路径中无法组合clip
和(在我看来这几乎是一个错误)。但是,如果您将选项添加到封闭范围,则操作将使用它。应用于上一个示例,剪切路径可以使用任何旋转方向:even odd rule
even odd rule
clip
\documentclass{standalone}
\usepackage{tikz}
\tikzset{invclip/.style={clip,insert path={{[reset cm]
(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)}}}}
\begin{document}
\begin{tikzpicture}[outer sep=0mm]
\coordinate (A) at (0,0);
\coordinate (B) at (1,0);
\coordinate (C) at (.5,1);
\coordinate (Ap) at (0,1);
\coordinate (Bp) at (1,1);
\coordinate (Cp) at (.5,0);
\begin{scope}[even odd rule]
\begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
\path[invclip]
(A) -- (B) -- (C) -- (A)
(Ap) -- (Bp) -- (Cp) -- (Ap);
\end{pgfinterruptboundingbox}
\fill[orange!50] (-1,-1) rectangle (2,2);
\draw (A) circle (2mm); % this is the little angle marker
\draw (B) circle (2mm); % this is the little angle marker
\draw (C) circle (2mm); % this is the little angle marker
\draw (Ap) circle (2mm); % this is the little angle marker
\draw (Bp) circle (2mm); % this is the little angle marker
\draw (Cp) circle (2mm); % this is the little angle marker
\end{scope}
\draw[red] (current bounding box.south west)
rectangle (current bounding box.north east);
\end{tikzpicture}
答案3
@Jack 发给我一个关于invclip
:
3D 图形中的反向剪辑-投影问题。
这个问题显示了@PaulGaborit 的答案中的一个问题,即双括号
\tikzset{invclip/.style={clip,insert path={{[reset cm] (-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt) }}}}
不限制范围reset cm
。事实上,在上面链接的例子中,它占用了四个。因此,在上面的链接中,我建议使用以下代码
\tikzset{
clip even odd rule/.code={\pgfseteorule}, % Credit to Andrew Stacey
invclip/.style={
clip,insert path=
[clip even odd rule]{
[reset cm](-\maxdimen,-\maxdimen)rectangle(\maxdimen,\maxdimen)
}
}
}
完整的例子如下
\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{graphs,graphs.standard}
\begin{document}
\tikzset{
clip even odd rule/.code={\pgfseteorule}, % Credit to Andrew Stacey
invclip/.style={
clip,insert path=
[clip even odd rule]{
[reset cm](-\maxdimen,-\maxdimen)rectangle(\maxdimen,\maxdimen)
}
}
}
\tikz{
\begin{pgfinterruptboundingbox}
\clip[invclip](1,0)--(0,1)--(0,-1)--(-1,0)--cycle;
\end{pgfinterruptboundingbox}
\graph{subgraph K_n[n=20,clockwise,radius=50]};
}
\end{document}
答案4
为了开始这项工作,这里有一个使用的方法fadings
。我不它的缺点是,为了使它工作,必须在淡入淡出中指定一个大矩形,希望它足够大 - 我不知道如何自动化。问题是,当指定淡入淡出时,所有内容外部褪色被认为是透明的,而对于这个,人们想要一切外部清晰可见。
\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{fadings}
\begin{document}
\begin{tikzfadingfrompicture}[name=fadeit]
\fill[white] (-10,-10) rectangle (10,10);
\path (0,0) coordinate (A) +(0:2) coordinate (B) +(50:2) coordinate (C);
\fill[black] (B) -- (A) -- (C) -- cycle;
\end{tikzfadingfrompicture}
\begin{tikzpicture}
\draw[path fading=fadeit,fit fading=false] (0,0) circle (1);
\end{tikzpicture}
\end{document}
它也不是那么好,因为必须从图片中分离出剪切的定义(我想知道是否可以使用remember picture
...来解决这个问题)。