我正在写一篇数学论文,其中包含一些图片和图表。由于我是 LaTeX 的初学者,也许我可以在这里直接向专家寻求帮助。我不确定您是否尊重这种提问方式,但我认为这对我来说是一种很好的学习方式!
例如,下面的图片取自第 111 页同源性理论作者:James W. Vick:
答案1
使用TikZ
。
在这种情况下,由于形状不规则,我会考虑使用外部工具(inkscape
和inkscape2tikz
,例如)来减轻工作量。
首先,我将原始图像导入inkscape
,然后使用“对象到路径”选项扭曲三个圆圈,直到得到不规则路径。然后我将路径保存为TikZ code (*.tex)
。这就是inkscape
产生的结果:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[y=0.80pt,x=0.80pt,yscale=-1, inner sep=0pt, outer sep=0pt]
\path[draw=black,thick] (457.1429,515.2193) .. controls (402.4772,580.5603) and (407.4258,577.4294) .. (318.5714,589.5050) .. controls (230.2170,601.5127) and (159.4945,516.4907) .. (188.5714,438.0764) .. controls (214.2857,368.7305) and (210.8684,318.6589) .. (318.5714,286.6479) .. controls (462.6395,243.8286) and (511.3212,450.4608) .. (457.1429,515.2193) -- cycle;\path (288.5714,540.9336)arc(-0.032:180.032:5.714286 and 125.714)arc(-180.032:0.032:5.714286 and 125.714) -- cycle;\path (294.2857,566.6479)arc(-0.083:180.083:1.428572 and 74.286)arc(-180.083:0.083:1.428572 and 74.286) -- cycle;\path (562.8571,490.9336)arc(-0.009:180.009:78.571426 and 67.143)arc(-180.009:0.009:78.571426 and 67.143) -- cycle;\path (540.0000,755.2193)arc(0.000:180.000:48.571430 and 37.143)arc(-180.000:0.000:48.571430 and 37.143) -- cycle;\path (500.0000,759.5051)arc(-0.000:180.000:58.571430 and 24.286)arc(-180.000:0.000:58.571430 and 24.286) -- cycle;\path (500.0000,760.9336)arc(0.000:180.000:112.857140 and 22.857)arc(-180.000:0.000:112.857140 and 22.857) -- cycle;\path (308.5714,769.5051)arc(-0.001:1.521:84.285713 and 180.000) -- (224.2858,769.5051) -- cycle;\path (417.1429,679.5051)arc(-0.001:358.327:140.000000 and 187.143);\path[miter limit=4.00,thick] (605.7143,592.3622)arc(-0.000:356.362:151.428570 and 165.714);\path[miter limit=4.00,thick] (542.8572,763.7908)arc(0.000:356.362:94.285713 and 48.571);
\path[draw=black,miter limit=4.00,thick] (566.6337,463.0661) .. controls (566.6337,580.4033) and (483.9700,588.3030) .. (409.0311,600.9337) .. controls (307.3211,618.0765) and (258.4203,498.8394) .. (291.4286,423.0661) .. controls (321.4797,354.0812) and (346.4143,319.4479) .. (451.8883,299.4842) .. controls (626.4874,266.4367) and (566.6337,374.3003) .. (566.6337,463.0661) -- cycle;
\path[draw=black,miter limit=4.00,line width=0.500pt] (462.8571,428.0765) .. controls (495.7835,431.6320) and (526.1145,517.8528) .. (480.8450,530.1033) .. controls (370.3986,559.9914) and (393.4636,569.1390) .. (341.4286,538.0765) .. controls (284.6129,504.1602) and (311.9087,520.6666) .. (303.6393,514.2165) .. controls (299.2618,510.8022) and (273.2117,513.6111) .. (242.8571,473.7908) .. controls (209.8031,430.4292) and (269.8988,368.1801) .. (302.8176,396.4594) .. controls (376.9162,460.1148) and (577.3715,370.4418) .. (475.7143,349.5050) .. controls (406.6638,335.2838) and (370.3789,418.0903) .. (462.8571,428.0765) -- cycle;
\end{tikzpicture}
\end{document}
现在,人们仍然可以扭曲其他形状来产生其他路径,但现在可以使用intersections
库轻松完成(而且所有的乐趣在哪里?);放置标签也是一件小事:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}[y=0.80pt,x=0.80pt,yscale=-1, inner sep=0pt, outer sep=0pt,every label/.style={font=\tiny}]
% A helping visual grid
\draw[gray!30] (100,200) grid (650,650);
% The irregular path to the left
\path[draw=red,thick] (457.1429,515.2193) .. controls (402.4772,580.5603) and (407.4258,577.4294) .. (318.5714,589.5050) .. controls (230.2170,601.5127) and (159.4945,516.4907) .. (188.5714,438.0764) .. controls (214.2857,368.7305) and (210.8684,318.6589) .. (318.5714,286.6479) .. controls (462.6395,243.8286) and (511.3212,450.4608) .. (457.1429,515.2193) -- cycle;\path (288.5714,540.9336)arc(-0.032:180.032:5.714286 and 125.714)arc(-180.032:0.032:5.714286 and 125.714) -- cycle;\path (294.2857,566.6479)arc(-0.083:180.083:1.428572 and 74.286)arc(-180.083:0.083:1.428572 and 74.286) -- cycle;\path (562.8571,490.9336)arc(-0.009:180.009:78.571426 and 67.143)arc(-180.009:0.009:78.571426 and 67.143) -- cycle;\path (540.0000,755.2193)arc(0.000:180.000:48.571430 and 37.143)arc(-180.000:0.000:48.571430 and 37.143) -- cycle;\path (500.0000,759.5051)arc(-0.000:180.000:58.571430 and 24.286)arc(-180.000:0.000:58.571430 and 24.286) -- cycle;\path (500.0000,760.9336)arc(0.000:180.000:112.857140 and 22.857)arc(-180.000:0.000:112.857140 and 22.857) -- cycle;\path (308.5714,769.5051)arc(-0.001:1.521:84.285713 and 180.000) -- (224.2858,769.5051) -- cycle;\path (417.1429,679.5051)arc(-0.001:358.327:140.000000 and 187.143);\path[miter limit=4.00,thick] (605.7143,592.3622)arc(-0.000:356.362:151.428570 and 165.714);\path[miter limit=4.00,thick] (542.8572,763.7908)arc(0.000:356.362:94.285713 and 48.571);
% The irregular path to the right
\path[draw=black,miter limit=4.00,thick,blue] (566.6337,463.0661) .. controls (566.6337,580.4033) and (483.9700,588.3030) .. (409.0311,600.9337) .. controls (307.3211,618.0765) and (258.4203,498.8394) .. (291.4286,423.0661) .. controls (321.4797,354.0812) and (346.4143,319.4479) .. (451.8883,299.4842) .. controls (626.4874,266.4367) and (566.6337,374.3003) .. (566.6337,463.0661) -- cycle;\node[circle,fill=black,inner sep=1.5pt,label={[yshift=-5pt,xshift=-10pt]below:{$y_4=x_0=y_0$}}] at (380,558) (ori) {};
% The irregular inner path
\path[draw=black,miter limit=4.00,line width=0.500pt,green,name path=inner curve] (462.8571,428.0765) .. controls (495.7835,431.6320) and (526.1145,517.8528) .. node[label={[xshift=14pt,yshift=-6pt,black]left:$\tau_2$}] {} (480.8450,530.1033) .. controls (370.3986,559.9914) and (393.4636,569.1390) .. (341.4286,538.0765) .. controls (284.6129,504.1602) and (311.9087,520.6666) .. (303.6393,514.2165) .. controls (299.2618,510.8022) and (273.2117,513.6111) .. (242.8571,473.7908) .. controls (209.8031,430.4292) and (269.8988,368.1801) .. node[label={[xshift=-6pt,black]left:$\tau_4$}] {} (302.8176,396.4594) .. controls (376.9162,460.1148) and (577.3715,370.4418) .. (475.7143,349.5050) .. controls (406.6638,335.2838) and (370.3789,418.0903) .. node[label={[xshift=-12pt,yshift=-26pt,black]left:$\tau_1$}] {} (462.8571,428.0765) -- cycle;
%% some paths to intersect the inner curve; we find the intersections and name them
\path[name path=line1] (ori) -- (335,300);
\path[name path=line2] (ori) -- (550,200);
\path[name path=line3] (400,570) -- (485,480);
\path[name intersections={of=line1 and inner curve, by = {int1}}];
\path[name intersections={of=line2 and inner curve, by = {int2,int3,int4}}];
\path[name path=line4] (int2) -- (400,300);
\path[name intersections={of=line4 and inner curve, by = {int7,int8}}];
\path[name intersections={of=line3 and inner curve, by = {int5}}];
%% draw the dashed paths
\draw[dashed] (ori) .. controls (340,500) and (370,470) .. node[label={[xshift=-4pt]left:$\beta_1$}] {} (int1);
\draw[dashed] (ori) .. controls (395,500) and (450,460) .. node[label={[xshift=11pt]left:$\beta_2$}] {} (int4) .. controls (455,410) .. (int2) .. controls (450,380) .. (int8);
\draw[dashed] (ori) .. controls (402,570) and (408,550) .. (int5);
%% place some labels
\node[circle,fill=black,inner sep=1.5pt,label={[yshift=3pt]above:$y_1$}] at (int1) {};
\node[circle,fill=black,inner sep=1.5pt,label={[yshift=3pt]above:$y_2$}] at (int8) {};
\node[circle,fill=black,inner sep=1.5pt,label={[yshift=3pt]above:$y_3$}] at (int5) {};
\node at (260,370) {\footnotesize$X_1$};
\node at (550,370) {\footnotesize$X_2$};
\node at (390,345) {\footnotesize$X_3$};
\end{tikzpicture}
\end{document}
谢谢保罗塞雷达他向我展示了 inkscape 中的“对象到路径”选项。
答案2
这个部分 Asymptote 代码具有完成它所需的所有元素,例如:
- 定义坐标数组、笔颜色和大小,
- 设置虚线间隔,
- 绘制标签、点、
- 设置 (La)Tex 前导码,
- 从点阵列构建曲线,
- 获取曲线的子路径,
- 计算曲线的交点,
- 使用沿路径的距离百分比来定位标签(
\tau_i
)。
topo.asy
:
size(400,400);
texpreamble("\usepackage{lmodern}");
pair[] leftPoints={
(109, 5),
(164, 25),
(181, 103),
(188, 152),
(174, 192),
(120, 191),
(80, 169),
(61, 113),
(53, 56),
(69, 18),
};
pair[] midPoints={
(83, 31),
(100, 49),
(119, 51),
(143, 53),
(155, 73),
(147, 98),
(119, 127),
(128, 148),
(141, 155),
(150, 147),
(152, 134),
(145, 127),
(113, 117),
(71, 127),
(53, 132),
(40, 127),
(31, 110),
(33, 87),
(45, 70),
(62, 58),
(76, 48),
(81, 41),
};
pair[] rightPoints={
(62, 8),
(94, 15),
(118, 38),
(132, 60),
(142, 114),
(139, 140),
(130, 175),
(102, 196),
(41, 183),
(10, 128),
(9, 73),
(28, 23),
};
pair[] leftDash={
(83, 31),
(81, 47),
(77, 62),
(73, 81),
(75, 95),
(73, 108),
(81, 134),
};
pair[] midDash={
(83, 31),
(89, 50),
(97, 62),
(107, 79),
(121, 97),
(123, 110),
(130, 118),
(131, 132),
(129, 142),
(124, 160),
};
pair[] rightDash={
(83, 31),
(89, 33),
(94, 37),
(97, 40),
(103, 42),
(109, 41),
(114, 44),
(124, 58),
};
guide buildCurve(pair[] p, bool cycled=true){
guide g=p[0];
for(int i=0;i<p.length;++i){
g=g..p[i];
}
if(cycled) g=g..cycle;
return g;
};
pen dashed=linetype(new real[] {4,3});
pen penLeft,penRight,penMid;
pen dashLeft,dashRight,dashMid;
real lineWidth=1.2pt;
penLeft=red+lineWidth;
penRight=darkgreen+lineWidth;
penMid=blue+lineWidth;
dashLeft=dashed+orange+lineWidth;
dashRight=dashed+olive+lineWidth;
dashMid=dashed+lightblue+lineWidth;
guide leftCurve, rightCurve, midCurve;
guide leftDashCurve, rightDashCurve, midDashCurve;
leftCurve=buildCurve(leftPoints);
rightCurve=buildCurve(rightPoints);
midCurve=buildCurve(midPoints);
leftDashCurve=buildCurve(leftDash,cycled=false);
rightDashCurve=buildCurve(rightDash,cycled=false);
midDashCurve=buildCurve(midDash,cycled=false);
draw(leftCurve,penLeft);
draw(rightCurve,penRight);
draw(midCurve,penMid);
draw(leftDashCurve,dashLeft);
draw(rightDashCurve,dashRight);
draw(midDashCurve,dashMid);
struct Point{
pair p;
Label L;
void operator init(pair p=(0,0), Label L=Label("")){
this.p=p;
this.L=L;
};
};
void putdot(pair p){
dot(p,darkblue,UnFill);
}
Point y4x0y0=Point(midDash[0], Label("$y_4=x_0=y_0$",midDash[0],S));
putdot(y4x0y0.p);
label(y4x0y0.L);
pair[] X={
(101, 165),
(27, 140),
(171, 139),
};
for(int i=0;i<X.length;++i){
label("$X_"+format("%d",i)+"$",X[i]);
}
real[] tauArcLen={-1, // not used, for convenient indexing
0.07,
0.2,
0.6,
0.8
};
pair[] tauRelPos={(0,0), // not used
N, E, N, W
};
real midArcLen=arclength(midCurve);
pair[] tauPoint=new pair[tauRelPos.length];
for(int i=1;i<tauPoint.length;++i){
tauPoint[i]=arcpoint(midCurve, tauArcLen[i]*midArcLen);
label("$\tau_"+format("%d",i)+"$", tauPoint[i], tauRelPos[i]);
}
guide leftDashTail=subpath(leftDashCurve,2,size(leftDashCurve)-1);
pair Mid_x_leftDash;
Mid_x_leftDash=intersectionpoint(midCurve,leftDashTail);
putdot(Mid_x_leftDash);
label("$y_1$",Mid_x_leftDash,NE,UnFill);
通过以下方式获取独立的 pdf 图片asy -f pdf topo.asy
答案3
有 PSTricks 但还未完成... 我们只需要耐心和毅力来找到绘制平滑曲线的临界点。一旦我们有了临界点,标记、划线等就很容易了。
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-eucl}
\usepackage{graphicx}
\newsavebox\IBox
\savebox\IBox{\includegraphics{image}}
\def\Row{10}
\def\Col{10}
\psset
{
xunit=\dimexpr\wd\IBox/\Col,
yunit=\dimexpr\ht\IBox/\Row,
linecolor=red,
dotscale=0.5,
}
\addtopsstyle{gridstyle}
{
griddots=0,
gridcolor=magenta,
gridwidth=0.4pt,
subgridcolor=green,
subgridwidth=0.2pt,
subgriddiv=5,
}
\everypsbox{\color{red}}
\begin{document}
\begin{pspicture}[showgrid=top](\Col,\Row)
\rput[bl](0,0){\usebox\IBox}
\pstGeonode%[CurveType=polyline]
(4.0,1.6){A}
(3.8,2.2){A2}
(3.4,2.6){B}
(2.8,3.0){C}
\pscurve(A)(A2)(B)(C)
\end{pspicture}
\end{document}