Den*_*ink 5 php fractals mandelbrot
有一段时间我现在对分形,它们背后的数学以及它们可以产生的视觉效果感兴趣.
我真的无法弄清楚如何将数学公式映射到绘制图片的一段代码.
给定mandelbrot集的这个公式: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;
}
Run Code Online (Sandbox Code Playgroud)
代码不完整,只是为了简洁而显示主要的迭代部分.
所以问题是:有人可以向我解释数学与代码的比较吗?
编辑:要清楚,我已经找到了解释数学的数十种资源,以及显示代码的数十种资源,但我无处可找到两者的完美解释.
use*_*291 18
免责声明.我以前对分形一无所知,但总是想知道,所以我读过维基百科的文章并决定写下我在这里找到的内容.正如他们所说,如果您想了解某些内容,请尝试向其他人解释.;)
好的,我们将对复杂的数字进行操作.一个复数实际上是一对(实数)数,因此,对于我们php程序员来说,让它成为一个双元素数组.
/// Construct a complex number from two reals
function cpl($re, $im) {
return array($re, $im);
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要告诉php如何在我们的复数上做算术.我们需要加法,乘法和mod("norm")运算符.(有关详细信息,请参阅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]);
}
Run Code Online (Sandbox Code Playgroud)
现在我们编写一个函数,如果给定(复杂)点$ c属于mandelbrot集,则返回true
c如果所有点z = z^2 + c都位于半径为2的圆内,则该点属于该集合.
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;
}
Run Code Online (Sandbox Code Playgroud)
其余的与数学无关,而且非常明显
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));
Run Code Online (Sandbox Code Playgroud)
结果

当然,这个代码是极端无效的.它的唯一目的是了解数学概念.