TikZ - 再帰的な円弧描画

TikZ - 再帰的な円弧描画

私は、ファレイ図を、これまで見てきたものと同様のものにしようとしています。 こちら(クリック)または次のスクリーンショットのように、

ここに画像の説明を入力してください

(画像出典:ウィキペディア

つまり、私は、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}

ここに画像の説明を入力してください

関連情報