Dados tres círculos mutuamente tangentes, siempre podemos encontrar dos círculos más que sean tangentes a los tres. Estos dos se llaman círculos apolíneos . Tenga en cuenta que uno de los círculos apolíneos podría estar alrededor de los tres círculos iniciales.
A partir de tres círculos tangentes, podemos crear un fractal llamado junta apolínea , mediante el siguiente proceso:
- Llame a los 3 círculos iniciales los círculos principales
- Encuentra los dos círculos apolíneos de los círculos principales
- Para cada círculo apolíneo:
- Para cada par de los tres pares de círculos principales:
- Llame al círculo apolíneo y a los dos círculos principales el nuevo conjunto de círculos principales y comience nuevamente desde el paso 2.
- Para cada par de los tres pares de círculos principales:
Por ejemplo, comenzando con círculos de igual tamaño, obtenemos:
Imagen encontrada en Wikipedia
Hay un poco más de notación que necesitamos. Si tenemos un círculo de radio r con centro (x, y) , podemos definir su curvatura como k = ± 1 / r . Por lo general, k será positivo, pero podemos usar k negativo para denotar el círculo que encierra a todos los otros círculos en la junta (es decir, todas las tangentes tocan ese círculo desde adentro). Luego podemos especificar un círculo con un triplete de números: (k, x * k, y * k) .
Para el propósito de esta pregunta, asumiremos un entero positivo k y racional x e y .
Se pueden encontrar más ejemplos de tales círculos en el artículo de Wikipedia .
También hay algunas cosas interesantes sobre las juntas integrales en este artículo (entre otras cosas divertidas con círculos).
El reto
Se le darán 4 especificaciones de círculo, cada una de las cuales se verá (14, 28/35, -112/105)
. Puede usar cualquier formato de lista y operador de división que sea conveniente, de modo que pueda simplemente eval
ingresar la entrada si lo desea. Puede suponer que los 4 círculos son tangentes entre sí y que el primero de ellos tiene una curvatura negativa. Eso significa que ya se te ha dado el círculo apolíneo circundante de los otros tres. Para obtener una lista de entradas de ejemplo válidas, consulte la parte inferior del desafío.
Escriba un programa o función que, dada esta entrada, dibuje una junta apolínea.
Puede tomar la entrada a través del argumento de función, ARGV o STDIN y renderizar el fractal en la pantalla o escribirlo en un archivo de imagen en el formato que elija.
Si la imagen resultante está rasterizada, debe tener al menos 400 píxeles en cada lado, con menos del 20% de relleno alrededor del círculo más grande. Puede dejar de recurrir cuando alcanza círculos cuyo radio es menor que 400 del círculo de entrada más grande, o círculos que son más pequeños que un píxel, lo que ocurra primero.
Debe dibujar solo contornos circulares, no discos completos, pero los colores de fondo y líneas son su elección. Los contornos no deben ser más anchos que una 200a del diámetro de los círculos exteriores.
Este es el código de golf, por lo que gana la respuesta más corta (en bytes).
Entradas de ejemplo
Aquí están todas las juntas integrales del artículo de Wikipedia convertidas al formato de entrada prescrito:
[[-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]]