12

I tried to draw a sequence of semicirles. This is my code.

    \documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc}
\usepackage{tkz-euclide}
\begin{document}
    \begin{tikzpicture}
    \tkzDefPoints{0/0/A,12/0/B}
    \tkzDefMidPoint(A,B) \tkzGetPoint{M}
    \tkzDrawSemiCircle(M,B)
    \tkzDrawSegments(A,B)
\tkzDefMidPoint(A,M) \tkzGetPoint{M_1}  
\tkzDrawSemiCircle(M_1,M)
\tkzDefMidPoint(B,M) \tkzGetPoint{M_2}  
\tkzDrawSemiCircle(M_2,B)
\tkzDefMidPoint(B,M_2) \tkzGetPoint{M_3}    
\tkzDrawSemiCircle(M_3,B)
\tkzDefMidPoint(B,M_3) \tkzGetPoint{M_4}    
\tkzDrawSemiCircle(M_4,B)
\tkzDefMidPoint(B,M_4) \tkzGetPoint{M_5}    
\tkzDrawSemiCircle(M_5,B)
\tkzDefMidPoint(M_1,M) \tkzGetPoint{C_1}    
\tkzDrawSemiCircle(C_1,M)
\tkzDefMidPoint(C_1,M) \tkzGetPoint{C_2}    
\tkzDrawSemiCircle(C_2,M)
\tkzDefMidPoint(C_2,M) \tkzGetPoint{C_3}    
\tkzDrawSemiCircle(C_3,M)
\tkzDefMidPoint(A,M_1) \tkzGetPoint{A_2}    
\tkzDrawSemiCircle(A_2,M_1)
\tkzDefMidPoint(A_2,M_1) \tkzGetPoint{A_3}  
\tkzDrawSemiCircle(A_3,M_1)
\tkzDefMidPoint(M,M_2) \tkzGetPoint{B_2}    
\tkzDrawSemiCircle(B_2,M_2)
\tkzDefMidPoint(A,A_2) \tkzGetPoint{A_4}    
\tkzDrawSemiCircle(A_4,A_2)
\tkzDefMidPoint(B_2,M_2) \tkzGetPoint{B_3}  
\tkzDrawSemiCircle(B_3,M_2)
\tkzDefMidPoint(M,B_2) \tkzGetPoint{B_4}    
\tkzDrawSemiCircle(B_4,B_2)
    \tkzLabelPoints[below](M,A,B,M_1,M_2,M_3)   
    \tkzDrawPoints[color=blue](A,B,M,M_1,M_2)
    \end{tikzpicture}
\end{document}

enter image description here

How to make a loop to draw a sequence semicircles?

1
  • 1
    Welcome! This looks like a good question ;).
    – cfr
    Commented Aug 8, 2023 at 2:36

3 Answers 3

9

Here's a recursive approach.

The sc = <spec>{<left>}{<right>} key is used to execute this recursion where

  • <left> stands for the left x value and
  • <right> stands for the right x value.

The <spec> consists of four parts: <action left><spec left><action right><spec right> where the actions are currently only s (draw a semicircle) or * (do nothing). The <spec left> and <spec right> consists of further <spec> for the left or the right half. A specification of . terminated the recursion at that point.

Code

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[
  x=12cm, y=12cm, radius=.5, start angle=0, delta angle=180,
  sc/.style n args={6}{% sc stands for semicircle
    radius/.evaluated=\pgfkeysvalueof{/tikz/x radius}/2,
    /utils/exec=\pgfmathsetmacro\scresult{(#5+#6)/2},
    style/.expanded={
      sc do #1={#2}{#5}{\scresult}, sc do #3={#4}{\scresult}{#6}}},
  sc do s/.style n args={3}{% s draws a semicircle
    insert path={(right:#3) arc[] \if.#1\else{[sc=#1{#2}{#3}]}\fi}},
  sc do */.code=]           % * does nothing
\draw (right:1) coordinate (right) arc[] coordinate[at end](left)
  [sc=s{s{s.s.}s{*.s{*.s.}}}% . terminates the recursion
      s{s{s.s.}s{*.s{*.s.}}}
      01];
\draw (left) -- (right)
  node foreach \pos/\t in {0/A, .25/M_1, .5/M, .75/M_2, .875/M_3, 1/B}[
    circle, fill=blue, inner sep=+0pt, minimum size=+2.5pt,
    label=below:$\t$, pos=\pos] {};
\end{tikzpicture}
\end{document}

Output

enter image description here

6

I'm not familiar with tkz-euclide, so I use TikZ directly. The basic idea is that the graphs between AM and MB are the same, which makes it possible for us to utilize the xshift feature.

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}
  \foreach \shift in {0cm, 8cm} {
    \tikzset{xshift=\shift}
    \foreach \radius in {0.5cm,1cm,2cm,4cm} {
      \draw (8,0) arc[start angle=0, end angle=180, radius=\radius];
    }
    \foreach \radius in {1cm,2cm} \draw (0,0) arc[start angle=180, end angle=0, radius=\radius];
    \draw (4,0) arc[start angle=0, end angle=180, radius=1cm];
  }
  \draw (0,0) -- (16,0) arc[start angle=0,end angle=180, radius=8cm];
  \foreach \x/\t in {0cm/A, 4cm/M_1, 8cm/M, 12cm/M_2, 14cm/M_3, 16cm/B} {
    \draw[fill = blue] (\x,0) circle[radius=1.5pt] node[below] {$\t$};
  }
\end{tikzpicture}
\end{document}

enter image description here

3

I propose a recursive function with expl3.

Here there are only 3 recursive levels.

To be able to identify the construction order, we have a starred version of the command. It will be necessary to proceed step by step to complete the construction of the semi-circles which do not enter into the recursion.

![enter image description here

\documentclass{article}
% https://tex.stackexchange.com/questions/692956/how-to-make-a-loop-to-draw-a-sequence-semicircles/692957#692957
\usepackage{tkz-euclide}
\ExplSyntaxOn
\int_new:N \l_numCircle_int
\int_set:Nn \l_numCircle_int { 0 }
%
\NewDocumentCommand \SemiCircle { s m m m }
{
    % #1 star if true, we write the number of the circle
    % #2 number of levels
    % #3 the first point of the segment
    % #4 the second point of the segment
    \__myrecur:nnnn {#1} {#2} {#3} {#4}
}

\cs_new:Npn \__myrecur:nnnn #1#2#3#4
{ 
    \int_compare:nNnF { #2 } = { 0 }
    { 
        \int_incr:N \l_numCircle_int
        %\tkzDefMidPoint(#3,#4) \tkzGetPoint{P#2}
        \coordinate(P#2) at ($(#3)!0.5!(#4)$);% for recursion
        % We create the center of the circle with the same index
        \coordinate(M\int_eval:n { \l_numCircle_int }) at ($(#3)!0.5!(#4)$);
        \tkzDrawSemiCircle(P#2,#4)
        \IfBooleanT {#1}
            { 
                \tkzLabelCircle[red](P#2,#4)(90){c\int_eval:n { \l_numCircle_int }}
            }

%%%%%%%%%%%%%         
        \__myrecur:nnnn { #1 } {\int_eval:n { #2 - 1 }} { #3 } { P#2 }
        \__myrecur:nnnn { #1 } {\int_eval:n { #2 - 1 }} { P#2 } { #4 }
        }
}


\ExplSyntaxOff
\begin{document}
\begingroup 
\small
\textbf{With * option}

\begin{tikzpicture}[scale=0.75]
\tkzDefPoints{0/0/A,12/0/B}
\tkzDrawSegments(A,B)
%
\SemiCircle*{3}{A}{B}
%
\SemiCircle*{1}{A}{M3}
\SemiCircle*{1}{M3}{M2}
\SemiCircle*{1}{M4}{M1}
\SemiCircle*{1}{M1}{M6}
\SemiCircle*{1}{M6}{M5}
\SemiCircle*{1}{M7}{B}
%
\SemiCircle*{1}{M10}{M1}
\SemiCircle*{1}{M13}{B}
%
\tkzDrawPoints[color=blue](A,M2,M1,M5,M13,B) 
\foreach \p/\n in {A/A,M2/M_1,M1/M,M5/M_2,M13/M_3,B/B}
    {
    \tkzLabelPoint(\p){$\n$}
    }
\end{tikzpicture}

\textbf{Without * option}

\begin{tikzpicture}[scale=0.75]
    \tkzDefPoints{0/0/A,12/0/B}
    \tkzDrawSegments(A,B)
    %
    \SemiCircle{3}{A}{B}
    %
    \SemiCircle{1}{A}{M3}
    \SemiCircle{1}{M3}{M2}
    \SemiCircle{1}{M4}{M1}
    \SemiCircle{1}{M1}{M6}
    \SemiCircle{1}{M6}{M5}
    \SemiCircle{1}{M7}{B}
    %
    \SemiCircle{1}{M10}{M1}
    \SemiCircle{1}{M13}{B}
    %
    \tkzDrawPoints[color=blue](A,M2,M1,M5,M13,B) 
    \foreach \p/\n in {A/A,M2/M_1,M1/M,M5/M_2,M13/M_3,B/B}
    {
        \tkzLabelPoint(\p){$\n$}
    }
\end{tikzpicture}

\textbf{With 5 levels and 3 levels}

\begin{tikzpicture}[scale=0.50]
    \tkzDefPoints{0/0/A,12/0/B}
    \tkzDrawSegments(A,B)
    %
    \SemiCircle{5}{A}{B}
    \SemiCircle{3}{B}{A}
    % \tkzDrawPoints[color=blue](A,M2,M1,M17,M29,B) 
    % \foreach \p/\n in {A/A,M2/M_1,M1/M,M17/M_2,M29/M_3,B/B}
    % {
    %     \tkzLabelPoint(\p){$\n$}
    % }
\end{tikzpicture}
\endgroup
\end{document}

enter image description here

You must log in to answer this question.

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