Dati tre cerchi reciprocamente tangenti, possiamo sempre trovare altri due cerchi tangenti a tutti e tre questi. Questi due sono chiamati cerchi apolloniani . Si noti che uno dei cerchi apolloniani potrebbe effettivamente essere attorno ai tre cerchi iniziali.
A partire da tre cerchi tangenti, possiamo creare un frattale chiamato guarnizione apolloniana , con il seguente processo:
- Chiama i 3 cerchi iniziali come i cerchi principali
- Trova i due cerchi apolloniani delle cerchie principali
- Per ogni circolo apolloniano:
- Per ogni coppia delle tre coppie di cerchi principali:
- Chiama la cerchia apolloniana e le due cerchie genitore la nuova serie di cerchie genitore e ricomincia dal passaggio 2.
- Per ogni coppia delle tre coppie di cerchi principali:
Ad esempio, iniziando con cerchi di uguali dimensioni, otteniamo:
Immagine trovata su Wikipedia
C'è ancora un po 'di notazione di cui abbiamo bisogno. Se abbiamo un cerchio di raggio r con centro (x, y) , possiamo definirne la curvatura come k = ± 1 / r . Di solito k sarà positivo, ma possiamo usare k negativo per indicare il cerchio che racchiude tutti gli altri cerchi nella guarnizione (cioè tutte le tangenti toccano quel cerchio dall'interno). Quindi possiamo specificare un cerchio con una tripletta di numeri: (k, x * k, y * k) .
Ai fini della presente domanda, si suppone intero positivo k e razionali x ed y .
Ulteriori esempi per tali cerchie sono disponibili nell'articolo di Wikipedia .
Ci sono anche alcune cose interessanti sulle guarnizioni integrali in questo articolo (tra le altre cose divertenti con le cerchie).
La sfida
Ti verranno fornite 4 specifiche del cerchio, ognuna delle quali apparirà (14, 28/35, -112/105)
. È possibile utilizzare qualsiasi formato elenco e operatore di divisione che sia conveniente, in modo tale da poter semplicemente eval
inserire l'input, se lo si desidera. Si può presumere che i 4 cerchi siano effettivamente tangenti tra loro e che il primo di essi abbia una curvatura negativa. Ciò significa che ti è già stato dato il circolo apolloniano circostante degli altri tre. Per un elenco di input di esempio validi, vedere il fondo della sfida.
Scrivi un programma o una funzione che, dato questo input, disegna una guarnizione apolloniana.
Puoi inserire input tramite argomento di funzione, ARGV o STDIN e visualizzare il frattale sullo schermo o scriverlo in un file di immagine in un formato a tua scelta.
Se l'immagine risultante viene rasterizzata, deve essere di almeno 400 pixel su ciascun lato, con un'imbottitura inferiore al 20% attorno al cerchio più grande. È possibile interrompere la ricorrenza quando si raggiungono cerchi il cui raggio è inferiore a un 400 ° del cerchio di input più grande o cerchi più piccoli di un pixel, a seconda di quale evento si verifichi per primo.
Devi disegnare solo contorni circolari, non dischi completi, ma i colori di sfondo e linee sono la tua scelta. I contorni non devono essere più larghi di un 200 ° del diametro dei cerchi esterni.
Questo è il golf del codice, quindi vince la risposta più breve (in byte).
Ingressi di esempio
Ecco tutte le guarnizioni integrali dell'articolo di Wikipedia convertite nel formato di input prescritto:
[[-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]]