Как "увеличить" часть набора Мандельброта?
Я создал файл Python для генерации образа Мандельброта. Первоначальный математический код не был моим, поэтому я его не понимаю - я лишь сильно изменил его, чтобы сделать его примерно в 250 раз быстрее (правило потоков!).
Во всяком случае, мне было интересно, как я могу изменить математическую часть кода, чтобы он отображал один конкретный бит. Вот часть математики:
for y in xrange(size[1]):
coords = (uleft[0] + (x/size[0]) * (xwidth),uleft[1] - (y/size[1]) * (ywidth))
z = complex(coords[0],coords[1])
o = complex(0,0)
dotcolor = 0 # default, convergent
for trials in xrange(n):
if abs(o) <= 2.0:
o = o**2 + z
else:
dotcolor = trials
break # diverged
im.putpixel((x,y),dotcolor)
И определения размера:
size1 = 500
size2 = 500
n=64
box=((-2,1.25),(0.5,-1.25))
plus = size[1]+size[0]
uleft = box[0]
lright = box[1]
xwidth = lright[0] - uleft[0]
ywidth = uleft[1] - lright[1]
что мне нужно изменить, чтобы он отображал определенный раздел набора?
2 ответа
Линия:
box=((-2,1.25),(0.5,-1.25))
это бит, который определяет область координатного пространства, которое отображается, поэтому вам просто нужно изменить эту строку. Первая пара координат - это верхний левый угол области, вторая - нижний правый.
Получить новую координату из изображения должно быть достаточно просто. У вас есть две системы координат, ваша "система изображений" размером 100x100 пикселей, начало координат в (0,0). А ваша "сложная" плоскость координат системы определяется "коробкой". Для X:
X_complex=X_complex_origin+(X_image/X_image_width)*X_complex_width
Ключом к пониманию того, как это сделать, является понимание того, что coords =
Линия делает:
coords = (uleft[0] + (x/size[0]) * (xwidth),uleft[1] - (y/size[1]) * (ywidth))
Фактически x
а также y
Зацикливаемые значения, соответствующие координатам экранного пикселя, переводятся в соответствующую точку на комплексной плоскости, на которую вы смотрите. Это означает, что (0,0)
координаты экрана будут переведены в верхнюю левую область (-2,1.25)
, а также (1,0)
будет таким же, но переместился на 1/500 расстояния (при условии, что окно шириной 500 пикселей) между -2
а также 0.5
х-координаты.
Это именно то, что делает эта строка - я расширю только бит X-координаты с более иллюстративными именами переменных, чтобы указать это:
mandel_x = mandel_start_x + (screen_x / screen_width) * mandel_width
(The mandel_
переменные относятся к координатам на комплексной плоскости, screen_
переменные относятся к экранным координатам отображаемого пикселя.)
Если вы хотите затем взять область экрана для увеличения, вы хотите сделать точно то же самое: взять экранные координаты верхней левой и нижней правой области, перевести их в координаты комплексной плоскости и сделать те новые переменные Uleft и Lright. то есть, чтобы увеличить поле, ограниченное экранными координатами (x1,y1)..(x2,y2), используйте:
new_uleft = (uleft[0] + (x1/size[0]) * (xwidth), uleft[1] - (y1/size[1]) * (ywidth))
new_lright = (uleft[0] + (x2/size[0]) * (xwidth), uleft[1] - (y2/size[1]) * (ywidth))
(Очевидно, вам нужно пересчитать размер, xwidth, ywidth и другие зависимые переменные на основе новых координат)
Если вам интересно, математика, лежащая в основе множества Мандельброта, не так сложна (просто сложна). Все, что он делает, это берет определенную координату, рассматривая ее как комплексное число, а затем многократно возводя ее в квадрат и добавляя к ней исходное число.
Для некоторых чисел выполнение этого приведет к тому, что результат будет расходиться, постоянно увеличиваясь до бесконечности при повторении процесса. Для других он всегда будет оставаться ниже определенного уровня (например, очевидно (0, 0, 0, 0) никогда не станет больше в этом процессе. Мандельброт (черная область) - это те координаты, которые не расходятся. Было показано, что если любое число выше квадратного корня из 5, оно будет расходиться - ваш код просто использует 2.0
как его приближение к sqrt(5)
(~2.236
), но это не будет иметь большого значения.
Обычно области, которые расходятся, наносятся на график с количеством итераций процесса, которое требуется для того, чтобы они превысили это значение (trials
переменная в вашем коде), которая производит цветные области.