![TikZ - 再帰的な円弧描画](https://rvso.com/image/286351/TikZ%20-%20%E5%86%8D%E5%B8%B0%E7%9A%84%E3%81%AA%E5%86%86%E5%BC%A7%E6%8F%8F%E7%94%BB.png)
私は、ファレイ図を、これまで見てきたものと同様のものにしようとしています。 こちら(クリック)または次のスクリーンショットのように、
(画像出典:ウィキペディア)
つまり、私は、6ページ目上部そこから残りの部分をどうするか考えていきたいと思います。とにかく、私はTikZを使ってこれをやりたいと思っていました。nレベルの深さでこれらの画像を生成できるアルゴリズム。
これが私の総当たり攻撃の試みです:
\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}
正直に言うと、私は TikZ と LaTeX プログラミングに関しては初心者です。ですから、どんなに基本的なことでも、どんなにか助かります。よろしくお願いします。
答え1
他の言語で示されている例と何ら変わりません。拡張に注意する必要がある箇所はわずかです。コード ゴルフは実際に試していませんが、機能しているようです。また、再帰の深さが増すにつれて、コード ゴルフは弱くなります。
\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}
答え2
数字なし:
\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}
答え3
昨日のコメントでも同じことを思っていましたこの答え近い主題について。このような再帰的な描画は、MetaPost や Asymptote など、(La)TeX と密接に関連しているが外部の言語で (比較的!) 簡単に実行できます。たとえば、元の投稿で説明した Farey 図に対して、MetaPost で「素早く雑に」試してみたのがこちらです。この言語で再帰的な描画を実装するのがいかに自然であるかがわかります。
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.
ということは、再帰的に何かを描画する必要がある場合は、毎回 MetaPost や Asymptote などの外部プログラムに戻ったほうがよいということでしょうか。PSTricks、Tikz、mfpic (この 3 つのうち、私が個人作業で定期的に使用しているもの) などの (La)TeX パッケージがいかに強力であるかを知っているので、これは少し驚きです。
編集ファレイの図と級数についてもう少し読んで、分母が再帰レベルの数以下の分数のみを許可するようにコードを改良してみました。このようにして、farey_diagram(0, 1, 1, 1, m)
ファレイ級数 Fm の数字 (のみ) をタイプセットし、対応する半円を描画します。
答え4
部分的な回答: これはシーケンスを正しく生成すると思います。 が必要です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}