TikZ - Dibujo de arco recursivo

TikZ - Dibujo de arco recursivo

Estoy intentando hacer diagramas de Farey similares a los vistos. aquí (haga clic)o la captura de pantalla de la siguiente manera,

ingrese la descripción de la imagen aquí

(fuente de imagen:Wikipedia)

Es decir, me gustaría un ejemplo del que se ve en elparte superior de la página 6. A partir de ahí espero poder descubrir cómo hacer el resto. De todos modos, quería hacer esto usando TikZ y esperaba tener algoalgoritmo que podría generar estas imágenes para n niveles de profundidad.

Aquí está mi intento de fuerza bruta:

    \documentclass[tikz]{standalone}
    \begin{document}
    \begin{tikzpicture}[scale=12]
    \draw (0,0) -- (1,0);
    \draw (0,0) -- (0,.618);
    \draw (1,0) -- (1,.618);
    \draw (1,0) arc (0:180:.5);

    \draw [dotted] (0,0) -- (0,-.1) node[below]{$\frac{0}{1}$};
    \draw [dotted] (1,0) -- (1,-.1) node[below]{$\frac{1}{1}$};

    \draw (1,0) arc (0:180:.25);
    \draw [dotted] (.5,0) -- (.5,-.1) node[below]{$\frac{1}{2}$};
    \draw (.5,0) arc (0:180:.25);

    \draw (1,0) arc (0:180:1/6);
    \draw [dotted] (2/3,0) -- (2/3,-.1) node[below]{$\frac{2}{3}$};
    \draw (2/3,0) arc (0:180:1/12);

    \draw (1/3,0) arc (0:180:1/6);
    \draw [dotted] (1/3,0) -- (1/3,-.1) node[below]{$\frac{1}{3}$};
    \draw (1/2,0) arc (0:180:1/12);

    \end{tikzpicture}
    \end{document}

Debo admitir que soy un novato en lo que respecta a TikZ y a la programación en LaTeX. Así que cualquier ayuda, por básica que sea, será apreciada. Gracias.

Respuesta1

No es diferente a los ejemplos dados en otros idiomas. Sólo hay unos pocos lugares donde es necesario ocuparse de la expansión. Realmente no opté por el código de golf, pero parece funcionar. Y se vuelve más débil a medida que aumenta la profundidad de la recursividad.

\documentclass[tikz]{standalone}
\newcount\recurdepth
\begin{document}
\begin{tikzpicture}[scale=2]
\draw[style=help lines] (0,0) grid[step=0.1cm] (1,0.5);

\def\myrecur#1#2#3#4#5{
\recurdepth=#5
\ifnum\the\recurdepth>1\relax
  \advance\recurdepth by-1\relax
  \edef\tempnum{\number\numexpr#1+#3\relax}%a+b
  \edef\tempden{\number\numexpr#2+#4\relax}%c+d
  \pgfmathparse{\tempnum/\tempden}\edef\temp{\pgfmathresult}%(a+b)/(c+d)

  \node[below=\the\recurdepth*1pt,scale=0.1*\the\recurdepth]at({(\temp)*1cm},0){$\frac{\tempnum}{\tempden}$};
  \draw[ultra thin,opacity=\the\recurdepth/10] ({(\temp)*1cm},0) arc (180:0:{((#3/#4)-\temp)*0.5cm});
  \draw[ultra thin,opacity=\the\recurdepth/10] ({(\temp)*1cm},0) arc (0:180:{(\temp-(#1/#2))*0.5cm});
  \begingroup
    \edef\ttempup{\noexpand\myrecur{\tempnum}{\tempden}{#3}{#4}{\the\recurdepth}}
    \edef\ttempdown{\noexpand\myrecur{#1}{#2}{\tempnum}{\tempden}{\the\recurdepth}}
    \ttempup\ttempdown
  \endgroup
\fi
}

\myrecur{0}{1}{1}{1}{6}

\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Respuesta2

Sin números:

\documentclass[tikz]{standalone}
\begin{document}
    \begin{tikzpicture}
        \draw [ultra thick] (-8,0) -- (8,0);
        \draw [ultra thick] (0,0) circle (8);
        \foreach \i in {0,1,2,3} {%
            \draw [ultra thick] (90*\i:8) arc (270+90*\i:180+90*\i:8);}
        \foreach \i in {0,1,...,7} {%
            \draw [very thick] (45*\i:8) arc (270+45*\i:135+45*\i:3.3);}
        \foreach \i in {0,1,...,15} {%
            \draw [thick] (22.5*\i:8) arc (270+22.5*\i:112.5+22.5*\i:1.6);}
        \foreach \i in {0,1,...,31} {%
            \draw [thin] (11.25*\i:8) arc (270+11.25*\i:101.25+11.25*\i:0.8);}
        \foreach \i in {0,1,...,63} {%
            \draw [ultra thin] (5.625*\i:8) arc (270+5.625*\i:95.625+5.625*\i:0.4);}
    \end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Respuesta3

Me preguntaba lo mismo ayer en los comentarios deesta respuestasobre un tema cercano. Para dibujos recursivos como este son (¡relativamente!) fáciles de hacer con lenguajes estrechamente relacionados con (La)TeX, pero externos a él, como MetaPost o Asymptote. Por ejemplo, aquí está mi intento "rápido y sucio" con MetaPost en el diagrama de Farey ilustrado en la publicación original. Muestra lo natural que es con este lenguaje implementar un dibujo recursivo:

input latexmp;
setupLaTeXMP(packages="amsmath", options = "12pt", textextlabel = enable, mode = rerun);

numeric u, m; 
u = 20cm; % scale
m = 8; % maximal denominator

% [a/b, c/d]: diameter, n: recursion level
def farey_diagram(expr a, b, c, d, n) = 
  draw halfcircle scaled ((c/d-a/b)*u) shifted (u*0.5[a/b,c/d], 0);
  if (n > 1) and (b+d <= m):
    label.bot("$\dfrac{" & decimal(a+c) & "}{"& decimal(b+d) & "}$", u*((a+c)/(b+d), 0));
    farey_diagram(a, b, a+c, b+d, n-1); farey_diagram(a+c, b+d, c, d, n-1);
  fi;
enddef;

beginfig(1);
  draw origin -- (u, 0);
  label.bot("$0$", origin); label.bot("$1$", (u, 0));
  % starting with 0/1 and 1/1; m levels of recursion needed
  farey_diagram(0, 1, 1, 1, m); 
endfig;
end.

ingrese la descripción de la imagen aquí

Entonces, ¿significa esto que deberíamos volver a programas externos como MetaPost o Asymptote cada vez que tengamos que dibujar algo de forma recursiva? Sería un poco sorprendente, ya que sé lo potentes que son paquetes (La)TeX como PSTricks, Tikz o mfpic (el que uso habitualmente para mi trabajo personal entre los tres).

EDITARDespués de leer un poco más sobre los diagramas y series de Farey, intenté refinar mi código, permitiendo solo fracciones con denominadores menores o iguales al número de niveles de recursividad. Así, farey_diagram(0, 1, 1, 1, m)escribe los números de la serie de Farey Fm (y sólo ellos) y dibuja los semicírculos correspondientes.

Respuesta4

Una respuesta parcial: creo que esto produce las secuencias correctamente. Necesita lualatex.

\documentclass[border=5]{standalone}
\usepackage{pgffor}
{\catcode`\%=11\gdef\pc{%}}
\directlua{
Rational = {}
Rational.__index = Rational

function Rational.new(p, q)
  local a, b, object
  a, b = p, q
  while b > 0 do
    a, b = b, a \pc b
  end
  object = {p=p/a, q=q/a}
  setmetatable(object, Rational)
  return object
end

function Rational:toString()
  return "" .. self.p .. "/" .. self.q
end

function Rational.__eq(P, Q)
  return (P.p == Q.p) and (P.q == Q.q)
end

function Rational.__add(P, Q)
  return Rational.new(P.p*Q.q + Q.p*P.q, P.q*Q.q)
end

function Rational.__sub(P, Q)
  return Rational.new(P.p*Q.q - Q.p*P.q, P.q*Q.q)
end

Sequence = {}
Sequence.__index = Sequence

function Sequence.new()
  local object = {data={}, n=0}
  setmetatable(object, Sequence)
  return object
end

function Sequence:get(i)
  return self.data[i]
end

function Sequence:append(v)
  table.insert(self.data, v)
  self.n = self.n + 1
end

function Sequence:toString()
  local s, i
  s = ""
  if self.n > 0 then
    s = s .. self.data[1]:toString()
    if self.n > 1 then
      for i = 2,self.n do
        s = s .. "," .. self.data[i]:toString()
      end
    end
  end
  return s
end

function farey_sequence(n)
  local f1, f2, t1, t2, i, j
  f1 = Sequence.new()
  f1:append(Rational.new(0,1))
  f1:append(Rational.new(1,1))
  if n > 1 then
    for i = 1,n do
      f2 = f1
      f1 = Sequence.new()
      for j = 1, f2.n-1 do
        t1 = f2:get(j)
        t2 = f2:get(j+1)
        f1:append(t1)
        if (t2-t1 == Rational.new(1, t1.q*t2.q)) and t1.q+t2.q <= n then 
          f1:append(Rational.new(t1.p+t2.p, t1.q+t2.q))
        end
      end
      f1:append(t2)
    end
  end
  return f1
end
}

\def\getfareysequence#1#2{%
  \edef#1{\directlua{tex.print(farey_sequence(#2):toString())}}%
}
\begin{document}
\begin{minipage}{4in}
\foreach \i in {1,...,8}{
 \getfareysequence\A{\i}
 $F_{\i}=\left\{\foreach \n/\d [count=\k] in \A {\ifnum\k>1,\fi\frac{\n}{\d}}\right\}$
\\[.5ex]
}
\end{minipage}
\end{document}

ingrese la descripción de la imagen aquí

información relacionada