Biorąc pod uwagę trzy wzajemnie styczne koła, zawsze możemy znaleźć dwa kolejne koła, które są styczne do wszystkich trzech z nich. Te dwa nazywane są kręgami Apolli . Zauważ, że jedno z kręgów apollińskich może faktycznie znajdować się wokół trzech początkowych kręgów.
Zaczynając od trzech stycznych kół, możemy utworzyć fraktal zwany uszczelką apollińską w następujący sposób:
- Nazwij pierwsze 3 kręgi kręgami nadrzędnymi
- Znajdź dwa koła apollońskie kręgów macierzystych
- Dla każdego koła apollińskiego:
- Dla każdej pary trzech par kręgów nadrzędnych:
- Nazwij krąg Apolliński i dwa koła nadrzędne nowym zestawem kół nadrzędnych i zacznij od kroku 2.
- Dla każdej pary trzech par kręgów nadrzędnych:
Np. Zaczynając od kół o równej wielkości, otrzymujemy:
Obraz znaleziony na Wikipedii
Potrzebujemy jeszcze jednej notacji. Jeśli mamy okrąg o promieniu r ze środkiem (x, y) , możemy zdefiniować jego krzywiznę jako k = ± 1 / r . Zwykle k będzie dodatnie, ale możemy użyć ujemnego k, aby oznaczyć okrąg, który otacza wszystkie pozostałe koła w uszczelce (tj. Wszystkie styczne dotykają tego okręgu od wewnątrz). Następnie możemy określić okrąg z trojaczką liczb: (k, x * k, y * k) .
Na potrzeby tego pytania przyjmiemy dodatnią liczbę całkowitą k oraz wymierną x i y .
Dalsze przykłady takich kręgów można znaleźć w artykule w Wikipedii .
W tym artykule jest też kilka interesujących rzeczy na temat uszczelek integralnych (między innymi zabawne rzeczy z kołami).
Wyzwanie
Otrzymasz 4 specyfikacje koła, z których każda będzie wyglądać (14, 28/35, -112/105)
. Możesz użyć dowolnego formatu listy i operatora podziału, który jest wygodny, dzięki czemu możesz po prostu eval
wprowadzić dane, jeśli chcesz. Możesz założyć, że 4 koła są rzeczywiście styczne do siebie i że pierwszy z nich ma krzywiznę ujemną. Oznacza to, że masz już otaczający apolloński krąg pozostałych trzech. Lista prawidłowych przykładowych danych wejściowych znajduje się w dolnej części wyzwania.
Napisz program lub funkcję, która przy tych wejściach rysuje uszczelkę apollińską.
Możesz przyjmować dane wejściowe za pomocą argumentu funkcji, ARGV lub STDIN i renderować fraktal na ekranie lub zapisywać go w pliku obrazu w wybranym formacie.
Jeśli powstały obraz jest rasteryzowany, musi mieć co najmniej 400 pikseli z każdej strony, z mniej niż 20% wypełnienia wokół największego koła. Możesz przestać się powtarzać, gdy dotrzesz do okręgów, których promień jest mniejszy niż 400. największego okręgu wejściowego, lub okręgów mniejszych niż piksel, w zależności od tego, co nastąpi wcześniej.
Musisz rysować tylko kontury kół, a nie pełne dyski, ale kolory tła i linii są twoim wyborem. Kontury nie mogą być szersze niż 200th średnicy zewnętrznych kół.
To jest kod golfowy, więc wygrywa najkrótsza odpowiedź (w bajtach).
Przykładowe dane wejściowe
Oto wszystkie integralne uszczelki z artykułu z Wikipedii przekonwertowane na określony format wejściowy:
[[-1, 0, 0], [2, 1, 0], [2, -1, 0], [3, 0, 2]]
[[-2, 0, 0], [3, 1/2, 0], [6, -2, 0], [7, -3/2, 2]]
[[-3, 0, 0], [4, 1/3, 0], [12, -3, 0], [13, -8/3, 2]]
[[-3, 0, 0], [5, 2/3, 0], [8, -4/3, -1], [8, -4/3, 1]]
[[-4, 0, 0], [5, 1/4, 0], [20, -4, 0], [21, -15/4, 2]]
[[-4, 0, 0], [8, 1, 0], [9, -3/4, -1], [9, -3/4, 1]]
[[-5, 0, 0], [6, 1/5, 0], [30, -5, 0], [31, -24/5, 2]]
[[-5, 0, 0], [7, 2/5, 0], [18, -12/5, -1], [18, -12/5, 1]]
[[-6, 0, 0], [7, 1/6, 0], [42, -6, 0], [43, -35/6, 2]]
[[-6, 0, 0], [10, 2/3, 0], [15, -3/2, 0], [19, -5/6, 2]]
[[-6, 0, 0], [11, 5/6, 0], [14, -16/15, -4/5], [15, -9/10, 6/5]]
[[-7, 0, 0], [8, 1/7, 0], [56, -7, 0], [57, -48/7, 2]]
[[-7, 0, 0], [9, 2/7, 0], [32, -24/7, -1], [32, -24/7, 1]]
[[-7, 0, 0], [12, 5/7, 0], [17, -48/35, -2/5], [20, -33/35, 8/5]]
[[-8, 0, 0], [9, 1/8, 0], [72, -8, 0], [73, -63/8, 2]]
[[-8, 0, 0], [12, 1/2, 0], [25, -15/8, -1], [25, -15/8, 1]]
[[-8, 0, 0], [13, 5/8, 0], [21, -63/40, -2/5], [24, -6/5, 8/5]]
[[-9, 0, 0], [10, 1/9, 0], [90, -9, 0], [91, -80/9, 2]]
[[-9, 0, 0], [11, 2/9, 0], [50, -40/9, -1], [50, -40/9, 1]]
[[-9, 0, 0], [14, 5/9, 0], [26, -77/45, -4/5], [27, -8/5, 6/5]]
[[-9, 0, 0], [18, 1, 0], [19, -8/9, -2/3], [22, -5/9, 4/3]]
[[-10, 0, 0], [11, 1/10, 0], [110, -10, 0], [111, -99/10, 2]]
[[-10, 0, 0], [14, 2/5, 0], [35, -5/2, 0], [39, -21/10, 2]]
[[-10, 0, 0], [18, 4/5, 0], [23, -6/5, -1/2], [27, -4/5, 3/2]]
[[-11, 0, 0], [12, 1/11, 0], [132, -11, 0], [133, -120/11, 2]]
[[-11, 0, 0], [13, 2/11, 0], [72, -60/11, -1], [72, -60/11, 1]]
[[-11, 0, 0], [16, 5/11, 0], [36, -117/55, -4/5], [37, -112/55, 6/5]]
[[-11, 0, 0], [21, 10/11, 0], [24, -56/55, -3/5], [28, -36/55, 7/5]]
[[-12, 0, 0], [13, 1/12, 0], [156, -12, 0], [157, -143/12, 2]]
[[-12, 0, 0], [16, 1/3, 0], [49, -35/12, -1], [49, -35/12, 1]]
[[-12, 0, 0], [17, 5/12, 0], [41, -143/60, -2/5], [44, -32/15, 8/5]]
[[-12, 0, 0], [21, 3/4, 0], [28, -4/3, 0], [37, -7/12, 2]]
[[-12, 0, 0], [21, 3/4, 0], [29, -5/4, -2/3], [32, -1, 4/3]]
[[-12, 0, 0], [25, 13/12, 0], [25, -119/156, -10/13], [28, -20/39, 16/13]]
[[-13, 0, 0], [14, 1/13, 0], [182, -13, 0], [183, -168/13, 2]]
[[-13, 0, 0], [15, 2/13, 0], [98, -84/13, -1], [98, -84/13, 1]]
[[-13, 0, 0], [18, 5/13, 0], [47, -168/65, -2/5], [50, -153/65, 8/5]]
[[-13, 0, 0], [23, 10/13, 0], [30, -84/65, -1/5], [38, -44/65, 9/5]]
[[-14, 0, 0], [15, 1/14, 0], [210, -14, 0], [211, -195/14, 2]]
[[-14, 0, 0], [18, 2/7, 0], [63, -7/2, 0], [67, -45/14, 2]]
[[-14, 0, 0], [19, 5/14, 0], [54, -96/35, -4/5], [55, -187/70, 6/5]]
[[-14, 0, 0], [22, 4/7, 0], [39, -12/7, -1/2], [43, -10/7, 3/2]]
[[-14, 0, 0], [27, 13/14, 0], [31, -171/182, -10/13], [34, -66/91, 16/13]]
[[-15, 0, 0], [16, 1/15, 0], [240, -15, 0], [241, -224/15, 2]]
[[-15, 0, 0], [17, 2/15, 0], [128, -112/15, -1], [128, -112/15, 1]]
[[-15, 0, 0], [24, 3/5, 0], [40, -5/3, 0], [49, -16/15, 2]]
[[-15, 0, 0], [24, 3/5, 0], [41, -8/5, -2/3], [44, -7/5, 4/3]]
[[-15, 0, 0], [28, 13/15, 0], [33, -72/65, -6/13], [40, -25/39, 20/13]]
[[-15, 0, 0], [32, 17/15, 0], [32, -161/255, -16/17], [33, -48/85, 18/17]]