![TikZ - Dibujo de arco recursivo](https://rvso.com/image/286351/TikZ%20-%20Dibujo%20de%20arco%20recursivo.png)
Estoy intentando hacer diagramas de Farey similares a los vistos. aquí (haga clic)o la captura de pantalla de la siguiente manera,
(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}
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}
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.
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}