Как «увеличить» часть набора Мандельброта? - PullRequest
5 голосов
/ 07 февраля 2009

Я создал файл 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 ]

14 голосов
/ 07 февраля 2009

Линия:

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
4 голосов
/ 07 февраля 2009

Ключ к пониманию того, как это сделать, состоит в том, чтобы понять, что делает строка 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-координата.

Это именно то, что делает эта строка - я расширю только бит X-координаты с более иллюстративными именами переменных, чтобы указать это:

mandel_x = mandel_start_x + (screen_x / screen_width) * mandel_width

(переменные 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 в вашем коде), то есть то, что создает цветные области.

...