Фракталы объяснили - PullRequest
       14

Фракталы объяснили

5 голосов
/ 16 сентября 2010

Некоторое время назад я интересовался фракталами, математикой за ними и визуальными эффектами, которые они могут создавать.

Я просто не могу понять, как отобразить математическую формулу на фрагмент кода, который рисует картину.
Учитывая эту формулу для множества Мандельброта: Pc(z) = z * z + c
Как это сравнить со следующим кодом:

$outer_adder = ($MaxIm - $MinIm) / $Lines;
$inner_adder = ($MaxRe - $MinRe) / $Cols;
for($Im = $MinIm; $Im <= $MaxIm; $Im += $outer_adder)
{
  $x=0;
  for($Re = $MinRe; $Re <= $MaxRe; $Re += $inner_adder)
  {
    $zr = $Re;
    $zi = $Im;
    for($n = 0; $n < $MaxIter; ++$n)
    {
      $a = $zr * $zr;
      $b = $zi * $zi;
      if($a + $b > 2) break;
      $zi = 2 * $zr * $zi + $Im;
      $zr = $a - $b + $Re;
    }
    $n = ($n >= $MaxIter ? $MaxIter - 1 : $n);
    ImageFilledRectangle($img, $x, $y, $x, $y, $c[$n]);
    ++$x;
  }
  ++$y;
}

Код не полный, просто для краткости показана основная часть итерации.

Итак, вопрос в том, может ли кто-нибудь объяснить мне, как математика сравнивается с кодом?

Редактировать: Для ясности, я нашел десятки ресурсов, объясняющих математику, и десятки ресурсов, показывающих код, но нигде не могу найти хорошего объяснения двух этих комбинаций.

1 Ответ

18 голосов
/ 16 сентября 2010

Отказ от ответственности.Я ничего не знал о фракталах раньше, но всегда хотел знать, поэтому я прочитал статью в Википедии и решил написать то, что нашел здесь.Как говорится, если вы хотите что-то понять, попробуйте объяснить это кому-то еще.;)

Хорошо, мы будем работать с комплексными числами.Комплексное число на самом деле представляет собой пару (действительных) чисел, поэтому для нас, программистов php, пусть это будет массив из двух элементов.

    /// Construct a complex number from two reals
    function cpl($re, $im) {
        return array($re, $im);
    }

Теперь нам нужно сказать php, как выполнять арифметику на нашемсложные числа.Нам понадобятся сложение, умножение и оператор мод («норма»).(подробности см. http://mathworld.wolfram.com/topics/ComplexNumbers.html).

    /// Add two complex numbers.
    function cadd($p, $q) {
        return cpl(
            $p[0] + $q[0],
            $p[1] + $q[1]);
    }

    /// Multiply two complex numbers.
    function cmul($p, $q) {
        return cpl(
            $p[0] * $q[0] - $p[1] * $q[1],
            $p[0] * $q[1] + $p[1] * $q[0]);
    }

    /// Return the norm of the complex number.
    function cmod($p) {
        return sqrt($p[0] * $p[0] + $p[1] * $p[1]);
    }

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

Точка c принадлежит множеству, если все точки z = z^2 + c лежат внутри круга с радиусом 2.

  • Начнем с комплексного числа z = (0, 0).
  • На каждом шаге мы вычисляем z = z * z + c.
  • Если modulus of z> 2 - то есть мы вне круга - точка НЕ ​​в наборе
  • В противном случае повторите шаг.

Чтобы предотвратить бесконечный цикл, ограничьте максимальное число итераций.

    function is_in_mandelbrot_set($c, $iterations) {
        $z = cpl(0, 0);
        do {
            if(cmod($z) >= 2)
                return false;
            $z = cadd(cmul($z, $z), $c);
        } while($iterations--);
        return true;
    }

Остальное не имеет ничего общего с математикой и вполнеочевидный

    function mandelbrot($img, $w, $h) {
        $color = imagecolorallocate($img, 0xFF, 0, 0);
        $zoom = 50;
        $iters = 30;

        for($x = 0; $x < $w; $x++) {
            for($y = 0; $y < $h; $y++) {

                // scale our integer points 
                // to be small real numbers around 0

                $px = ($x - $w / 2) / $zoom;
                $py = ($y - $h / 2) / $zoom;

                $c = cpl($px, $py);

                if(is_in_mandelbrot_set($c, $iters))
                    imagesetpixel($img, $x, $y, $color);
            }
        }

        return $img;
    }

    $w = 200;
    $h = 200;

    header("Content-type: image/png");
    imagepng(
        mandelbrot(
            imagecreatetruecolor($w, $h), $w, $h));

Результат

alt text

Конечно, этот код крайне неэффективен.Его единственная цель - понять математическую концепцию.

...