答案1
你可以让 Ti钾Z 进行计算:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections, decorations.markings}
\newlength{\cx}
\newlength{\cy}
\NewDocumentCommand{\extractangle}{ m O{0pt} O{0pt} m }{
\pgfextractx{\cx}{\pgfpointanchor{#4}{center}}
\pgfextracty{\cy}{\pgfpointanchor{#4}{center}}
\pgfmathparse{atan2(\cy-(#3),\cx-(#2))}
\let#1=\pgfmathresult
}
\begin{document}
\begin{tikzpicture}[
font=\scriptsize,
dot/.style={
node contents={},
inner sep=0.5pt,
circle,
fill,
},
three arrow heads/.style={
postaction={
decorate,
decoration={
markings,
mark={
at position -3.885cm
with { \arrow{>}}
},
mark={
at position -2.25cm
with { \arrow{>}}
},
mark={
at position -0.635cm
with { \arrow{>}}
}
}
}
}
]
% base line
\draw (0:3) -- (180:3);
% coordinates and calculations
\coordinate (A) at (120:2);
\coordinate (B) at (90:2);
\coordinate (C) at (60:2);
\path[name path=CircleA] (A) circle[radius=0.25];
\path[name path=CircleB] (B) circle[radius=0.25];
\path[name path=CircleC] (C) circle[radius=0.25];
\path[name path=Arc] (0:2) arc[start angle=0, end angle=180, radius=2];
\path[name intersections={of=CircleA and Arc, name=i}];
\path[name intersections={of=CircleB and Arc, name=j}];
\path[name intersections={of=CircleC and Arc, name=k}];
\extractangle{\angleA}[cos(120)*2cm][sin(120)*2cm]{i-1}
\extractangle{\angleB}{i-1}
\extractangle{\angleC}{j-1}
\extractangle{\angleD}[0pt][2cm]{j-1}
\extractangle{\angleE}[0pt][2cm]{j-2}
\extractangle{\angleF}{j-2}
\extractangle{\angleG}{k-1}
\extractangle{\angleH}[cos(60)*2cm][sin(60)*2cm]{k-1}
% squarish shape
\draw[three arrow heads]
([yshift=0.25cm]120:2) coordinate[label={left:{$B$}}]
arc[start angle=90, end angle={\angleA}, radius=0.25]
coordinate[label={below:{$C$}}]
arc[start angle=\angleB, end angle=\angleC, radius=2]
coordinate[label={below:{$D$}}]
arc[start angle={360+\angleD}, end angle=\angleE, radius=0.25]
coordinate[label={below:{$E$}}]
arc[start angle=\angleF, end angle=\angleG, radius=2]
coordinate[label={below:{$F$}}]
arc[start angle=\angleH, end angle=90, radius=0.25]
coordinate[label={right:{$G$}}]
-- ++(0,1.25) coordinate[label={above right:{$H$}}]
-| coordinate[label={above left:{$A$}}] cycle;
% big arc
\draw
(0:2)
arc[start angle=0, end angle=60, radius=2]
node[dot, label={below:{$-\bar{e}$}}]
(B) node[dot, label={below:{$i$}}]
(A) node[dot, label={below:{$e$}}]
arc[start angle=120, end angle=180, radius=2];
\end{tikzpicture}
\end{document}
一些帮助您理解代码的解释:
答案2
通过数学找到解决方案。
多次使用的值存储在/tikz
命名空间中的值键中,这就是我使用短命令名的原因\tvo
。
小圆弧的半径以及它们的角度将被计算并存储在small radius
和中small angle
。
代码
\documentclass[tikz]{standalone}
\newcommand*\tvo[1]{\pgfkeysvalueof{/tikz/#1}}
\usetikzlibrary{arrows.meta}
\tikzset{
pics/arrow/.style={/tikz/sloped, /tikz/allow upside down,
code=\pgfarrowdraw{#1}}, pics/arrow/.default=>}
\begin{document}
\begin{tikzpicture}[
> = {Straight Barb[angle=60:3pt 1.5]},
declare function={chord(\a,\r)=2*\r*sin(\a/2);},
missing angle/.initial=5,
big radius/.initial=4,
big angle/.initial=60,
small radius/.initial/.evaluated={chord(\tvo{missing angle},\tvo{big radius})},
small angle/.initial/.evaluated={\tvo{big angle}+\tvo{missing angle}/2},
r-/.style={radius=\tvo{small radius}}, r+/.style={radius=\tvo{big radius}},
top/.initial=6,
node font=\scriptsize]
\draw (left:5) -- (right:5);
\draw[r+] (left:\tvo{big radius})
arc[start angle=180, delta angle=-\tvo{big angle}] coordinate (e)
(right:\tvo{big radius})
arc[start angle=0, delta angle= \tvo{big angle}] coordinate (e');
\coordinate (A) at (e|-0,\tvo{top})
coordinate (B) at ([shift=(up:\tvo{small radius})] e)
coordinate (G) at ([shift=(up:\tvo{small radius})] e')
coordinate (H) at (e'|-0,\tvo{top})
coordinate (i) at (up:\tvo{big radius});
\draw[r+] (A) -- pic{arrow} (B)
arc[start angle=90, delta angle=-\tvo{small angle}, r-] coordinate (C)
arc[start angle=180-\tvo{big angle}-\tvo{missing angle},
end angle=90+\tvo{missing angle}] coordinate (D)
arc[start angle=180+\tvo{missing angle},
end angle=-\tvo{missing angle}, r-] coordinate (E)
arc[start angle=90-\tvo{missing angle},
end angle=\tvo{big angle}+\tvo{missing angle}] coordinate (F)
arc[end angle=90, delta angle=-\tvo{small angle}, r-] % -- (G) % maybe
-- pic{arrow} (H) -- pic{arrow} cycle;
\foreach \lab/\pos in {A/above left, B/left, C/below, D/below,
E/below, F/below, G/right, H/above right}
\node[\pos] at (\lab) {$\lab$};
\foreach \pos/\lab in {e, i, e'/-\bar e}
\fill (\pos) circle[radius=.7pt] node[below=3pt]{$\lab$};
\end{tikzpicture}
\end{document}
输出
答案3
纯粹为了比较,这里有一个替代的 Latex 友好语言版本,称为元帖子。
它被包装在luamplib
包中,因此您需要使用它来编译它lualatex
。
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);
path base, hemi, loop;
base = (left -- right) scaled 200;
hemi = halfcircle scaled 300;
% controlling parameters...
numeric r, c, h; r = 1.27324; c = 12; h = 100;
pair A, H;
A = point 4-r of hemi shifted (0, h);
H = point r of hemi shifted (0, h);
loop = buildcycle(
A -- point 4-r of hemi,
subpath (3, 0) of halfcircle scaled 2c shifted point 4-r of hemi,
subpath (4-r,2) of hemi,
subpath (5, -1) of fullcircle scaled 2c shifted point 2 of hemi,
subpath (2, r) of hemi,
subpath (4, 1) of halfcircle scaled 2c shifted point r of hemi,
point r of hemi -- H -- A
);
% draw loop withcolor red; % to see the points round the loop...
% for i=1 upto length loop: dotlabel.top(decimal i, point i of loop); endfor
interim ahangle := 30;
drawarrow subpath (-1.5, 0.5) of loop;
drawarrow subpath (0.5, 19.5) of loop;
drawarrow subpath (19.5, 20.5) of loop;
draw base;
draw subpath (0, r) of hemi;
draw subpath (4-r, 4) of hemi;
begingroup; interim labeloffset := 8; dotlabeldiam := 2;
dotlabel.bot("$-\bar e$", point r of hemi);
dotlabel.bot("$i$", point 2 of hemi);
dotlabel.bot("$e$", point 4-r of hemi);
endgroup;
drawoptions(withcolor 2/3 red);
label.ulft("$\scriptstyle A$", A);
label.lft ("$\scriptstyle B$", point 1 of loop);
label.bot ("$\scriptstyle C$", point 4 of loop);
label.bot ("$\scriptstyle D$", point 6 of loop);
label.bot ("$\scriptstyle E$", point 14 of loop);
label.bot ("$\scriptstyle F$", point 16 of loop);
label.rt ("$\scriptstyle G$", point 19 of loop);
label.urt ("$\scriptstyle H$", H);
drawoptions();
endfig;
\end{mplibcode}
\end{document}
笔记
绘制是通过三条独立的路径完成的:
base
只是一条通过原点的水平线;hemi
使用内置路径halfcircle
来获得适当缩放的半圆,但只绘制了部分;并且loop
。loop
用宏创建buildcycle
:此宏获取路径列表并生成由路径重叠部分组成的封闭路径。如果所有路径都朝同一方向运行,则效果最佳。构建的复杂路径
buildcycle
最终可能会产生比其所需更多的控制点;额外的点不会影响形状,但它们确实使它更难使用point x of y
,subpath (a, b) of y
因此注释掉的代码包含一个循环,我用它来计算出箭头和字母标签的正确子路径。“控制参数”为:
r
控制点“e”和“-e”的位置。r=0 表示在底面上,r=2 表示“e”与“i”重合;c
是三个点处圆的半径;h
是“A”在“e”上方的高度。