我在 Freyd 和 Scedrov 的书《范畴,寓言》中看到了这样的图表:
我想知道如何使用tikz-cd
,TikZ
或任何其他 LaTeX 包的组合。
编辑:
自从我提出这个问题以来,我想出了一个更基本的解决方案(通过一些研究和大量的怪物攻击),因为我需要一种更直接的方法来制作这种图表,但最重要的是,因为我远不是 TikZ 专家。我还忘了提到,由于图表用于定义,因此不能将其作为图形包含在内,它必须准确地放在需要的位置。
我的解决方案如下:
\documentclass{tufte-book}
\usepackage{tikz-cd,scalerel,multirow}
%% Puncture mark for removing equations in diagrams
\def\punct{%
\tikz{
\draw (0.08,0) -- (0.18,0);
\draw (0,0.08) -- (0,0.18);
\draw (-0.08,0) -- (-0.18,0);
\draw (0,-0.08) -- (0,-0.18);
}
}
%quantifiers
\def\diagforall{%
\tikz{\draw (0,-1) -- (0,1);\node at (0,1.2) {$\forall$};}
}
\def\diagexists{%
\tikz{\draw (0,-1) -- (0,1);\node at (0,1.2) {$\exists$};}
}
\def\diagexun{%
\tikz{\draw (0,-1) -- (0,1);\node at (0,1.2) {$\exists !$};}
}
%% Larger \cdot
\def\Lcdot{%
\raisebox{-0.7ex}{\hstretch{2}{\vstretch{2}{\cdot}}}
}
\begin{document}
\begin{displaymath}
\begin{array}{ccccc}
%% Quantifiers
& \multirow{3}{*}{\diagforall} & & \multirow{3}{*}{\diagexun} & \\
%% Diagram in first column
\begin{tikzcd}
\Lcdot \ar{r} & \Lcdot \arrow[yshift=-0.9ex]{r}{\ast} \ar[yshift=0.9ex]{r} & \Lcdot
\end{tikzcd} & &
%% Diagram in third column
\begin{tikzcd}
& \Lcdot \ar{d} & \\
\Lcdot \ar{r} & \Lcdot \arrow[yshift=-0.9ex]{r}{\ast} \ar[yshift=0.9ex]{r} & \Lcdot
\end{tikzcd}
& &
%% Diagram in last column
\begin{tikzcd}
& \Lcdot \ar{d} \ar{dl} & \\
\Lcdot \ar{r} & \Lcdot \arrow[yshift=-0.9ex]{r}{\ast} \ar[yshift=0.9ex]{r} & \Lcdot
\end{tikzcd} \\
%% This is padding
& & & & \\
\end{array}
\end{displaymath}
\end{document}
输出结果如下:
通过稍微调整,我能够制作出
这正是我最初想要的。现在,我不得不改变两个水平箭头之间的穿刺标记,因为当我尝试我的小 TikZ 命令时,它出现了这样的结果:
有什么办法可以让小穿刺痕迹发挥作用吗?
答案1
另一种解决方案是使用MetaPost。我已将其包含在 LuaLaTeX 程序中(MetaPost 嵌入 LuaTeX),以方便排版。如果您不使用 LuaLaTeX,您可以通过以下方式将此程序生成的 PDF 图形包含在您自己的文件中:graphicx
包。或者你可以使用gmp
包将此代码包含在 LaTeX/PDFLaTeX/XeLaTeX 文件中。
编辑根据 Barbara Beeton 对 Qrrbrbirlbel 的回答的评论,我把垂直线及其标记加粗了。为了使后者加粗,我切换到了 XITS 字体:与 Latin Modern 默认字体相反,量词符号在 XITS 中有加粗版本。
\documentclass[border=2mm]{standalone}
\usepackage{unicode-math}
\setmainfont{XITS}
\setmathfont{XITS Math}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
v := 1.75cm; len := 3bp; input boxes
def bullet = btex $\bullet$ etex enddef;
def cross = image(for angl = 0 step 90 until 270:
draw ((.5len, 0) -- (len, 0)) rotated angl; endfor)
enddef;
beginfig(1);
for i = 1 upto 9:
boxit.a[i](bullet); a[i].c = ((i-1)*v, 0); drawunboxed(a[i]);
endfor
for i = 1 upto 3:
boxit.cr[i](cross); cr[i].c = ((1.5+ 3(i-1))*v, 0); drawunboxed(cr[i]);
endfor
for i = 1 step 3 until 9:
drawarrow a[i].e -- a[i+1].w;
drawarrow a[i+1].ne -- a[i+2].nw; drawarrow a[i+1].se -- a[i+2].sw;
endfor
for i = 1,2:
boxit.u[i](bullet); u.[i]c = a[5+3(i-1)].c + (0, v);
drawunboxed(u[i]); drawarrow u[i].s -- a[5+3(i-1)].n;
endfor
drawarrow u2.sw -- a7.ne;
pickup pencircle;
draw (2.5v, 1.25v)--(2.5v, -.5v);
label.top(btex $\mathbf\forall$ etex, (2.5v, 1.25v));
draw (5.5v, 1.25v)--(5.5v, -.5v);
label.top(btex $\mathbf{\exists!}$ etex, (5.5v, 1.25v));
endfig;
\end{mplibcode}
\end{document}
答案2
这是一个可能的解决方案xypic
。由于我不知道双箭头的十字符号,所以我使用了+
。之后,您可以替换它。
\documentclass[11pt,a4paper]{report}
\usepackage{amsmath}
\usepackage[all,cmtip]{xy}
\usepackage{lipsum}
\begin{document}
\lipsum*[2]
\begin{equation}
\begin{gathered}
\xymatrix@C=.5cm@R=.5cm{%
&&& \forall \ar@{-}[ddd] & &&& \exists! \ar@{-}[ddd] \\
&&& & & \bullet\ar[d] & &&& \bullet\ar[d] \ar[dl] \\
\bullet \ar[r] & \bullet \ar@<1ex>[r] \ar@<-1ex>[r] \ar@{}[r]|{+} & \bullet & & \bullet\ar[r] & \bullet \ar@<1ex>[r] \ar@<-1ex>[r] \ar@{}[r]|{+} & \bullet & & \bullet\ar[r] & \bullet \ar@<1ex>[r] \ar@<-1ex>[r] \ar@{}[r]|{+} & \bullet \\
&&& & &&&
}
\end{gathered}
\end{equation}
\lipsum*[2]
\end{document}
答案3
代码
\documentclass{standalone}
\usepackage{tikz-cd}
\usetikzlibrary{decorations.markings, arrows.meta, calc}
\tikzset{my Barb/.tip={Straight Barb[round,angle=45:1pt 3]}}
\tikzset{
plus mark/.style={-,
decorate, decoration={markings, mark=at position .5 with {
\draw[-,dash pattern=on #1 off 2*#1 on #1] (left:2*#1) -- (right:2*#1)
(up:2*#1) -- (down:2*#1);}}},
plus mark/.default=1pt}
\tikzcdset{
dots in cells/.style={
cells={nodes={shape=circle, fill, draw, inner sep=+0pt, minimum size=+3pt}}}}
\newcommand*\plar[1][r]{%
\arrow[#1, plus mark]
\arrow[#1, shift left=1.5]
\arrow[#1, shift right=1.5]}
\begin{document}
\begin{tikzcd}[dots in cells, cells={nodes={outer sep=+2pt}},
every arrow/.append style=-my Barb,
every matrix/.append style={name=M},
/tikz/execute at end picture={
\foreach \col/\t[evaluate={\Col=int(\col+1)}] in {3/\forall,6/\exists!}
\draw ([yshift=.2cm]perpendicular cs: horizontal line through={(M.north)},
vertical line through={($(M-2-\col)!.5!(M-2-\Col)$)})
node[above](@){$\t$}
-- ([yshift=-.3cm]@|-M.south);}]
& & &[-.5em] & {} \dar & &[-.5em] & {} \dar\dlar & \\
{} \rar & {} \plar & {} & {} \rar & {} \plar & {} & {} \rar & {} \plar & {}
\end{tikzcd}
\end{document}