Возникли проблемы при вычислении итераций множества Мандельброта - PullRequest
4 голосов
/ 13 февраля 2012

Итак, я прочитал эту статью: http://www.wikihow.com/Plot-the-Mandelbrot-Set-By-Hand Но я застрял на шаге 7. Я рисую набор на холсте javascript.

Все, что мне нужно, это, в основном, значение C, я думаю.

for (var y = 0; y < ImageHeight; y++) {
    for (var x = 0; x < ImageWidth; x++) {

        // Pixel-Position for ImageObject
        var xy = (x + y * image.width) * 4;

        // Convert Image-Dimension to a radius of 2
        var xi = ((x / ImageWidth) * 4) - 2;
        var yi = ((y / ImageHeight) * 4) - 2;

        for (var n = 0; n < MaxIterations; n++) {

            // Complex number stuff..?
            z = (xi*xi) + (yi*yi) + c;
            c = 0; // Somethig with z ..?

            if (z < 4) {

                image.data[xy] = inner_color[0];
                image.data[xy+1] = inner_color[1];
                image.data[xy+2] = inner_color[2];
                image.data[xy+3] = Math.round(n * cdiff);

            } else {

                image.data[xy] = outer_color[0];
                image.data[xy+1] = outer_color[1];
                image.data[xy+2] = outer_color[2];
                image.data[xy+3] = Math.round(n * cdiff);

                break;
            }
        }
    }
}

Я также много читал о мнимых числах и прочем, но я не совсем понял, как с ними рассчитывать. И они кажутся мне как-то бесполезными, потому что вам все равно придется преобразовывать их обратно в реальные числа, чтобы, например, выполнять логические операции в javascript.

Вот как это выглядит: [удалено]
Если вы удалите 2 в конце URL, вы увидите другую версию, где я просто переписал небольшой фрагмент кода на c ++. Но масштабирование как-то странно, поэтому я хочу написать все это самостоятельно ...

Я понял основную концепцию создания множества Мандельброта, но, как я уже сказал, сложная часть беспокоит меня. Может быть, есть еще более простое объяснение?

1 Ответ

15 голосов
/ 30 марта 2012

Вы должны сначала понять это:

z = z^2 + c

Давайте разберемся.

И z, и c являются комплексными числами (и недавний вопрос научил меня это подчеркивать, они имеют дробных цифр и могут выглядеть следующим образом: c=-0.70176-0.3842i). Комплексные числа могут иметь часть, которая не является реальной, правильный термин - мнимая часть, и вы записываете одиночное комплексное число в виде:

(a + bi), что совпадает с: (a + b*i)

Если b равно 0, то у вас есть a + 0i, который просто a, поэтому без мнимой части у вас есть действительное число.

В вашей ссылке не упоминается самое важное свойство комплексного числа, особенно свойство его мнимой части, которая i == sqrt(-1). В области действительных чисел нет такого понятия, как квадратный корень из отрицательного числа, и именно здесь комплексные числа входят и позволяют получить квадратный корень из -1. Давайте поднимем i до степени 2: i^2 == -1, магия!

Мнимая часть (i) должна обрабатываться вами (специальным квадратом), или язык программирования, с которым вы работаете, предложит вам сложный тип, который обрабатывает его для вас.

Теперь вернемся к расширению z^2:

z == (a+bi), следовательно z^2 == (a+bi)^2, поэтому z^2 == (a^2 + bi^2 + 2*a*bi).

Давайте разберем это также:

  • a^2 => это просто, это действительное число
  • bi^2 => Хитрая часть. Это действительно b^2*i^2. И мы получили здесь i^2, то есть -1, что делает его b^2*-1 или: -b^2. Так что это тоже реальное число.
  • 2*a*b*i => это будет мнимая часть

Результат: z^2 = (a^2-b^2+2*a*bi)

Пример (немного более подробный. Вы можете думать об этом как о первой итерации в цикле):

z = (5 + 3i)
z^2 = (5 + 3i)^2
    = (5^2 + 3^2*i^2 + 2*5*3i)
    = (25 + 9i^2 + 30i)
    = (25 + 9*-1 + 30i)
    = (25 - 9 + 30i)
    = (16 + 30i)

Теперь, если вы понимаете итерацию и умножение комплексных чисел, несколько слов о Мандельброте (и о значении c):

Когда вы хотите создать множество Мандельброта, вы действительно ищете точки на комплексной плоскости, которые никогда не уходят в бесконечность, если их повторять - скажем, 50 раз - с итерацией, описанной выше. Набор Мандельброта - это черная часть обычно видимых картин "Мандельброта", а не блестящая цветная часть.

Mandelbort set, taken from Wikipedia

Обычный рабочий процесс такой:

  • выберите точку на комплексной плоскости, скажем (1.01312 + 0.8324i) => это будет значение c!
  • перед первой итерацией поместите (0, 0i) в z, затем выполните итерацию несколько раз, как указано ранее => z = z^2 + c. Да, вы возводите в квадрат точку и добавляете к ней ту же точку, это очень важный атрибут из набора Мандельброта . Для начала сделайте это 50 раз. В результате вы получите комплексное число.
  • если какая-либо часть результирующего комплексного числа (действительного или мнимого) равна или больше 2, то мы предполагаем, что эта точка будет уходить в бесконечность, и мы считаем эту точку не равной часть набора Мандельброта *. Это тот случай, когда вам нужно раскрасить точку (это красочная часть набора Мандельброта). Если обе части комплексного числа меньше 2, мы предполагаем, что точка никогда не уйдет в бесконечность (даже если повторяется более миллиона раз), и рассматриваем эту точку как часть множества Мандельброта, и ее цвет будет черным.
  • повтор (выберите следующую точку, поместите ее значение в c, поместите ноль в z и вычислите)

* на самом деле, проверка, является ли точка частью набора, немного сложнее, но это хорошо работает для прототипов

...