![](/processed_images/dca9f31ca768a44e00.jpg)
png
Этот фрактал основан на бесконечном построении касающихся окружностей.
Суть этого фрактала заключается в следующем: изначально у нас есть минимальный набор окружностей (три), у которого мы знаем положение центров и радиусы. Далее необходимо строить касательную к каждой из них, и к каждой из образовавшихся, и так до бесконечности, чтобы пространство полностью заполнялось без пересечений окружностей.
![](/processed_images/079e9c99fb32c36500.webp)
png
Поэтому, для того, чтобы нарисовать при помощи программы такой фрактал, необходимо сначала решить простую задачу:
Как, зная координаты центра и радиус трех окружностей, найти все касательные к ним?
Но для начала свойство двух касательных окружностей: если касание внешнее, то расстояние между центрами окружностей равно сумме их радиусов; если касание внутреннее, то расстояние между центрами равно разности их радиусов, взятое по модулю.
![](/processed_images/8dd0153a3e68544800.webp)
png
Учитывая, что окружностей три, а каждая может касаться четвертой двумя способами, получаем всего 2³=8 способов как могут касаться три окружности с четвертой, которую надо найти.
Благодаря этому свойству можем составить систему из трех уравнений, где есть три неизвестных. За m1, m2, m3 я обозначил параметры - внешнее или внутреннее касание для конкретной окружности: +1 означает внешнее касание, -1 внутреннее (рисунок 4).
Благодаря этому свойству можем составить систему из трех уравнений, где есть три неизвестных. За m1, m2, m3 я обозначил параметры - внешнее или внутреннее касание для конкретной окружности: +1 означает внешнее касание, -1 внутреннее.
![](/processed_images/317ad607fcc4b81100.webp)
png
Такую систему уравнений надо как-то решить. Поначалу она может показаться страшной, и на самом деле так и есть :) И проще её решить аналитически, чем при помощи всяких численных методов. Но это аналитическое решение не способна выдать ни одна система символьных вычислений, а если может, то ей не хватит памяти, либо формула выходит километровой, и ее невозможно использовать в программе (если вы найдете такую программу, которая сможет решить эту систему, и там не будет километровой формулы, то я скинусь вам на шаурму). Поэтому единственный доступный способ - решать на бумажке, делая огромное число замен.
![](/processed_images/3601259840ca2db000.webp)
png
Пример решения системы уравнений для различных m
Я не буду здесь приводить решение, потому что это слишком сложно: я ещё в школе пытался решить эту систему, но так и не смог; лишь после двух курсов в университете, мои мозги достаточно подготовились, чтобы решить ее до конца. Если захотите повторить мой подвиг, то вот вам подсказка: делайте больше замен, заменяя некоторые части на новые переменные.
Одна очень важная деталь, которую я выяснил насчет решения: оно численно неустойчиво даже для вещественных чисел двойной точности (это при том, что там вычисляются только формулы!), поэтому я использовал библиотеку для длинной арифметики boost::multiprecision::cpp_bin_float
, где задал размер вещественного числа в 40 байт (320 бит).
Далее, имея функцию нахождения касательных окружностей к трем данным, можно легко написать функцию, которая из изначального набора строит весь фрактал. В этой функции будет использоваться рекурсия, а так же там надо учесть, чтобы не возникали окружности, которые уже рисовались.
Таким образом получается первая картинка.
Ну а на следующей картинке показаны первые эксперименты: внутрь всех окружностей была вписана изначальная окружность.
![](/processed_images/7d7a9c8b0d6e1ee400.jpg)
png
А на следующей картинке такой процесс повторялся до бесконечности (причем, чтобы выглядело красиво, цвет более глубоких итераций ставился на более блёклый).
![](/processed_images/48adcc45418acfbb00.jpg)
png
Далее планируется переписать код, чтобы он стабильно работал для всех случаев, когда может происходить деление на ноль; вообще создать целую библиотеку вычислений касательных окружностей для разных случаев; создание различных анимаций; создание кругов Аполлона со случайными характеристиками на всех уровнях.
Если у вас появятся идеи того, что ещё можно натворить с кругами Аполлона — предлагайте их в комментариях.