10

I need to draw an integration path on top of a circle (with TikZ because I assume it's the best tool for the job), but I don't have any experience with it, and I literally don't know how to start, so what could a skeleton be?

Here it is

Enter image description here

7
  • 3
    ctan.org, tikz. Start with the minimal introduction. It shows you concepts quickly, so you can use the big manual for directed search. // Try drawing simple parts first. Refine step by step. Add your attempts as code to your question, so we can have a look.
    – MS-SPO
    Mar 27, 2023 at 20:07
  • Try using FreeTikz
    – John Smith
    Mar 27, 2023 at 20:57
  • Look at this helpful answer: tex.stackexchange.com/questions/669907/…
    – John Smith
    Mar 27, 2023 at 20:58
  • 1
    Welcome to TeX.SX! Please help us help you and add a minimal working example (MWE) that illustrates your problem. Reproducing the problem and finding out what the issue is will be much easier when we see compilable code, starting with \documentclass{...} and ending with \end{document}.
    – DG'
    Mar 27, 2023 at 21:23
  • 3
    Just a funny remark: in the TiKZ manual one of the fictional people to which the tutorials at the beginning are aimed is just named Karl and titled A Picture for Karl’s Students :-) Mar 28, 2023 at 8:28

3 Answers 3

20

You can let TikZ do the calculations:

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

enter image description here

Some explanations to help you understand the code:

  • I mostly used polar coordinates. These are very helpful when drawing things that are based on circles or arcs. The syntax is (A:B) where A is the angle (0 degrees is to the east) and B is the distance from the origin.
  • I used the intersections library to find intersections of different paths, mainly of circles and arcs. Below I added the drawing with some of the helper paths colored to make it more clear where I used intersections. See the PGF manual for an in-depth explanation of how this library works.
  • I used a macro (\extractangle) for which I found inspiration here to help me calculate the angle of a given cartesian coordinate using the atan2() function provided by PGF. I added two optional arguments to shift the origin, which was needed to calculate all the needed angles.
  • Knowing all the coordinates and angles, I was finally able to draw the shapes, and to add the labels and decorations.

enter image description here

2
  • Thanks for the explanations, understand it much better now.
    – Karl
    Mar 27, 2023 at 22:42
  • 1
    @Karl I added some explanations to my answer. Both, the \extractangle macro which essentially uses the atan2() function to calculate the angle from a given cartesian coordinate as well as the intersections library are necessary for doing the calculations. Mar 27, 2023 at 22:42
11

A solution via math.

Values that are used more than once are stored in value-keys in the /tikz namespace which is why I'm using a short command name for \tvo.

The radius of the small arcs as well as their angles will be calculated and stored in small radius and small angle.

Code

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

Output

enter image description here

2
  • Hm, you are right: intersections are not really needed, now that I see this solution =D Mar 27, 2023 at 23:39
  • @JasperHabicht Eh, the intersections library is a valid approach. May be best combined with the spath3 library to just remove the various parts of the circles that shouldn't be drawn and just coming those that should. Would mean even less calculations. Mar 28, 2023 at 0:21
7

Purely for comparison, here is a version in an alternative Latex-friendly language, called Metapost.

enter image description here

This is wrapped up in the luamplib package, so you need to compile it with 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}

Notes

  • The drawing is done with three separate paths: base is just a horizontal line through the origin; hemi uses the built-in path halfcircle to get a suitably scaled semi-circle, but only parts of it are drawn; and loop.

  • loop is created with the buildcycle macro: this macro takes a list of paths and produces a closed path that consists of the overlapping parts of the paths. It works best if all the paths are running in the same direction.

  • A complicated path built by buildcycle may end up with more control points than it needs; the extra points don't affect the shape but they do make it harder to use point x of y and subpath (a, b) of y, so the commented out code contains a loop that I used to work out the correct subpaths for the arrows and the lettered labels.

  • The "controlling parameters" are: r that controls the position of the points "e" and "-e". r=0 would be on the base, r=2 would make "e" coincide with "i"; c is the radius of the circles at the three points; h is the height of "A" above "e".

1
  • Thank you, I didn't even know Metapost existed
    – Karl
    Mar 28, 2023 at 23:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .