困难的 TikZ 图片

困难的 TikZ 图片

我需要在一个圆圈上方绘制一条积分路径(使用 TikZ 因为我认为它是完成这项工作的最佳工具),但我对此没有任何经验,而且我真的不知道如何开始,那么骨架应该是什么呢?

这里是

在此处输入图片描述

答案1

你可以让 TiZ 进行计算:

\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}

在此处输入图片描述

一些帮助您理解代码的解释:

  • 我主要使用极坐标。当绘制基于圆或圆弧的东西时,它们非常有用。语法是(A:B)A角度(0 度是向东),B 是与原点的距离。
  • 我使用该intersections库来查找不同路径的交点,主要是圆和圆弧。下面我添加了绘图,其中的一些辅助路径被着色,以便更清楚地显示我使用交点的位置。请参阅PGF 手册深入了解该库的工作原理。
  • \extractangle我使用了一个我从中得到灵感的宏( )这里帮助我使用atan2()PGF 提供的函数计算给定笛卡尔坐标的角度。我添加了两个可选参数来移动原点,这是计算所有所需角度所必需的。
  • 知道了所有的坐标和角度后,我终于能够绘制形状,并添加标签和装饰。

在此处输入图片描述

答案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 ysubpath (a, b) of y因此注释掉的代码包含一个循环,我用它来计算出箭头和字母标签的正确子路径。

  • “控制参数”为:r控制点“e”和“-e”的位置。r=0 表示在底面上,r=2 表示“e”与“i”重合; c是三个点处圆的半径;h是“A”在“e”上方的高度。

相关内容