Отказ от ответственности.Я ничего не знал о фракталах раньше, но всегда хотел знать, поэтому я прочитал статью в Википедии и решил написать то, что нашел здесь.Как говорится, если вы хотите что-то понять, попробуйте объяснить это кому-то еще.;)
Хорошо, мы будем работать с комплексными числами.Комплексное число на самом деле представляет собой пару (действительных) чисел, поэтому для нас, программистов 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));
Результат
Конечно, этот код крайне неэффективен.Его единственная цель - понять математическую концепцию.