我尝试使用 XY-pic 绘制图表。以下代码已经运行良好,但我对“绕行弧”有问题。
\documentclass{article}
\usepackage[all]{xy}
\begin{document}
\[
\xymatrix@C=5mm@R=10mm{
&&&&&&&&&&&& \\
{\bullet}\ar[ru]^A\ar[rr] && {\bullet}\ar[r]\ar[ru]^B & {\bullet}\ar[r] & {\bullet}\ar[rrr]\ar[ru]^D &&& {\bullet}\ar[r] & {\bullet}\ar[rrr]\ar[ru]^F &&& {\bullet}\ar[r] & {\bullet}\ar`^u[u]`/20pt[ul]`[ullllllllllll]`l[llllllllllll][llllllllllll] \\ %\ar`^l[llllllllllll]`_dr[llllllllllll][llllllllllll] \\
&& \ar[ru]_C &&&& \ar[ru]_E &&&& \ar[ru]_G & \ar[ru]_H &
}
\]
\end{document}
我想实现以下两件事:
- 右侧的弯曲应为半圆。
- 左侧的弯曲应与右侧的弯曲相同。
我尝试了几个小时,但还是无法让它工作。出了什么问题?
答案1
经过一个小时的仔细研究XY 指南我有一个解决方案。我将尽力在下面解释。
以下是 LaTeX 源代码:
\documentclass[border=5mm]{standalone}
\usepackage[pdf, matrix, arrow, curve]{xy}
\begin{document}
\begin{xymatrix}@C5mm@R10mm{
&&&&&&&&&&&&
\\
&
\bullet \ar[rr] \ar[ru]^{A} &&
\bullet \ar[r] \ar[ru]^{B} &
\bullet \ar[r] &
\bullet \ar[rrr] \ar[ru]^{D} &&&
\bullet \ar[r] &
\bullet \ar[r] \ar[ru]^{F} &
\bullet \ar[r] &
\bullet \ar@{->} `r/5mm[u]
`[u]
`[lllllllllll]
`[l]
[llllllllll]
\\
&&&\ar[ru]_C
&&&&\ar[ru]_E
&&\ar[ru]_G
&\ar[ru]_H
\\}
\end{xymatrix}
\end{document}
笔记
除了循环返回箭头外,这或多或少和您所拥有的一样。
我的箭有四个弯曲的部分。
第一个
`r/5mm[u]
说的是“添加一条从右边开始半径为 5 毫米的曲线,结束于从起点向上的节点方向”。第二条命令
`[u]
说“添加一条半径相同的曲线,从我们现在的位置开始,到原始起点向上的节点方向结束”第三个
`[lllllllllll]
说“添加一个长直线段,以四分之一曲线结束,该曲线指向距离原始起点左侧很多位置的节点(仍然是节点 H)第四条
`[l]
是“从我们到达的位置到终点添加一条四分之一曲线,该曲线指向我们开始位置左侧一个位置的节点方向”。此处添加额外的曲线不会产生任何影响。
最后,您必须为箭头的末端指定一个目标,因此我添加了
[llllllllll]
指向 H 左侧 10 个位置的节点(即 A)。请注意,最后一个没有反引号。如果您想要更圆润的曲线,您应该减少行高而不是增加半径。如果您进行实验,您会发现当您将半径增加到行高的一半以上时,箭头位置会变得混乱。
答案2
这是一个luamplib
版本(LuaLatex + Metapost),您正在等待xypic
调试帮助...
附有内联评论:
\documentclass[border=5mm]{standalone}
\usepackage{fontspec}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);
u := 10mm; % unit scale
z.A = origin; % points for each bullet
z.B = (2u,0);
z.C = (3u,0);
z.D = (4u,0);
z.E = (7u,0);
z.F = (8u,0);
z.G = (10u,0);
z.H = (11u,0);
% define two handy arrow paths,
path arrow_away, arrow_into;
arrow_away = origin -- right scaled 2u rotated 57;
arrow_into = arrow_away shifted - point 1 of arrow_away;
% make the arrow heads narrower
ahangle := 30;
% draw dots and away arrows
forsuffixes $=A,B,D,F:
drawdot z$ withpen pencircle scaled 3;
drawarrow subpath (0.1, 0.9) of arrow_away shifted z$;
label.ulft("$" & str $ & "$", point 0.5 of arrow_away shifted z$);
endfor
% draw dots and into arrows
forsuffixes $=C,E,G,H:
drawdot z$ withpen pencircle scaled 3;
drawarrow subpath (0.1, 0.9) of arrow_into shifted z$;
label.lrt("$" & str $ & "$", point 0.5 of arrow_into shifted z$);
endfor
% macro to save typing
vardef connect(expr a, b) =
drawarrow a--b cutbefore fullcircle scaled 0.4u shifted a
cutafter fullcircle scaled 0.4u shifted b;
enddef;
connect(z.A,z.B);
connect(z.B,z.C);
connect(z.C,z.D);
connect(z.D,z.E);
connect(z.E,z.F);
connect(z.F,z.G);
connect(z.G,z.H);
% do the loop connection separately
drawarrow z.H { right } .. { left }
point 1 of arrow_away shifted z.H shifted 5 right
--
point 1 of arrow_away shifted z.A shifted 5 left
{ left } .. { right } z.A
cutbefore fullcircle scaled 0.4u shifted z.H
cutafter fullcircle scaled 0.4u shifted z.A;
endfig;
\end{mplibcode}
\end{document}
如果您更喜欢倾斜度较小的曲线,您可以用以下方式替换复飞箭头:
drawarrow halfcircle rotated -90 shifted 1/2 up scaled 1.7u shifted z.H --
halfcircle rotated +90 shifted 1/2 up scaled 1.7u shifted z.A
cutbefore fullcircle scaled 0.4u shifted z.H
cutafter fullcircle scaled 0.4u shifted z.A;