我想生成以下维恩图:
可以通过以下方式生成
\documentclass[tikz,margin=0pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,intersections}
\begin{document}
\pagestyle{empty}
\makeatletter
\tikzset{
use path for main/.code={%
\tikz@addmode{%
\expandafter\pgfsyssoftpath@setcurrentpath\csname tikz@intersect@path@name@#1\endcsname
}%
},
use path for actions/.code={%
\expandafter\def\expandafter\tikz@preactions\expandafter{\tikz@preactions\expandafter\let\expandafter\tikz@actions@path\csname tikz@intersect@path@name@#1\endcsname}%
},
use path/.style={%
use path for main=#1,
use path for actions=#1,
}
}
\makeatother
\begin{tikzpicture}
\path[name path=XCircle] (-0.8cm,0) circle (1.5cm);
\path[name path=YCircle] (0.8cm,0) circle (1.5cm);
\path[name path=WholeSet] (-2.3cm,-1.5cm) rectangle (2.3,1.5);
\begin{scope} [even odd rule]
\clip (0.8cm,0) circle (1.5cm) (-2.3cm,-1.5cm) rectangle (2.3,1.5);
\draw [use path=XCircle, fill=gray!70];
\end{scope}
\draw [use path=XCircle];
\draw [use path=YCircle];
\end{tikzpicture}
\end{document}
但是,我希望使用use path
而不是直接指定形状,即我希望用\clip (0.8cm,0) circle (1.5cm) (-2.3cm,-1.5cm) rectangle (2.3,1.5);
类似的东西替换线条\clip [use path=YCircle, use path=WholeSet];
。但是,我上面写的行将生成错误的输出:
我的问题是:我怎样才能获得奇偶剪辑并use path=
一起工作?
答案1
代码use path
覆写当前路径与命名路径。因此,第二个use path
替换第一个,第一个实际上被忽略。要实现所需的目的,您需要一个附加版本的密钥use path
。使用几个\expandafter
s(可能太多了)您可以做到这一点。
\documentclass[tikz,margin=3pt]{standalone}
%\url{http://tex.stackexchange.com/q/301335/86}
\usepackage{tikz}
\usetikzlibrary{shapes,intersections}
\begin{document}
\pagestyle{empty}
\makeatletter
\def\@appendnamedsoftpath#1{%
\pgfsyssoftpath@getcurrentpath\@temppatha
\expandafter\let\expandafter\@temppathb\csname tikz@intersect@path@name@#1\endcsname
\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\@temppatha\expandafter\expandafter\expandafter{\expandafter\@temppatha\@temppathb}%
\pgfsyssoftpath@setcurrentpath\@temppatha
}
\def\@appendnamedpathforactions#1{%
\pgfsyssoftpath@getcurrentpath\@temppatha
\expandafter\let\expandafter\@temppathb\csname tikz@intersect@path@name@#1\endcsname
\expandafter\def\expandafter\@temppatha\expandafter{\csname @temppatha\expandafter\endcsname\@temppathb}%
\let\tikz@actions@path\@temppatha
}
\tikzset{
use path for main/.code={%
\tikz@addmode{%
\expandafter\pgfsyssoftpath@setcurrentpath\csname tikz@intersect@path@name@#1\endcsname
}%
},
append path for main/.code={%
\tikz@addmode{%
\@appendnamedsoftpath{#1}%
}%
},
use path for actions/.code={%
\expandafter\def\expandafter\tikz@preactions\expandafter{\tikz@preactions\expandafter\let\expandafter\tikz@actions@path\csname tikz@intersect@path@name@#1\endcsname}%
},
append path for actions/.code={%
\expandafter\def\expandafter\tikz@preactions\expandafter{\tikz@preactions
\@appendnamedpathforactions{#1}}%
},
use path/.style={%
use path for main=#1,
use path for actions=#1,
},
append path/.style={%
append path for main=#1,
append path for actions=#1
}
}
\makeatother
\begin{tikzpicture}
\path[name path=XCircle] (-0.8cm,0) circle (1.5cm);
\path[name path=YCircle] (0.8cm,0) circle (1.5cm);
\path[name path=WholeSet] (-2.3cm,-1.5cm) rectangle (2.3,1.5);
\begin{scope} [even odd rule]
\clip [use path=YCircle, append path=WholeSet];
\fill [use path=XCircle, gray!70];
\end{scope}
\draw [use path=XCircle];
\draw [use path=YCircle];
\end{tikzpicture}
\end{document}
(我不会\draw
在剪辑里面添加路径,它会画出一些奇怪的东西。虽然它被后面的\draw
命令透支了,但最好不要画一些不必要的东西。)
答案2
我只是想指出,可能没有必要对 PGF 的系统层进行如此深入的研究,该系统层有以下几点需要说明\pgfsyssoftpath@
:
另一方面,作为用户您永远不会直接使用这些命令,它们被描述为低级界面的一部分。
当然,摆弄它是很有趣的,但是这里介绍如何使用基本的 LaTeX 宏来完成它\newcommand
:
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\newcommand\XCircle {(-0.8cm,0) circle (1.5cm)}
\newcommand\YCircle {(0.8cm,0) circle (1.5cm)}
\newcommand\WholeSet{(-2.3cm,-1.5cm) rectangle (2.3,1.5)}
\begin{scope}[even odd rule]
\clip \YCircle \WholeSet;
\fill[gray!70] \XCircle;
\end{scope}
\draw \XCircle;
\draw \YCircle;
\end{tikzpicture}
\end{document}
这种方法存在一些细微的差别(例如,在我的版本中,每次使用路径时都会对其进行解析,因此它会受到坐标系变换等的影响),但至少很容易看出发生了什么。