Mandelbrot set

Filed under Fractals, الرياضيات on ٢٨ يناير ٢٠٢٥. Last updated on ٢٨ يناير ٢٠٢٥.

toc

一起来玩吧!

如果你不知道这些参数都是什么,你可以先看完这篇文章再来试试!

scale: 1,xoffset: 0,yoffset: 0,colorScale: 5,maxIterations: 50,z: 0,

Scale Step: 0.1

X Step: 0.1

Y Step: 0.1

Mandelbrot set

有两个非常重要的参数来定义一个Mandelbrot set: 起始点zz,以及常数cc

fc(z)=z2+cf_c(z) = z^2 + c

为了渲染Mandelbrot图形,我们需要计算出每个点迭代的次数,然后把不同的迭代次数渲染成不同的颜色。

迭代函数

  1. 设置最大迭代次数。如果没有这个限制,有些点在算法上根本不会收敛。
  2. 设置退出条件。虽然我们可以设置不同的退出条件,但重点是我们至少需要一个退出条件来结束循环。
function f(z: Complex, c: Complex) {
    return z.mul(z).add(c);
}

function iterateF(z: Complex, c: Complex, maxIterations: number): number {
    let i = 0;
    while (i < maxIterations) {

        if (z.abs() > 2) {
            break
        }
        z = f(z, c);
        i++;
    }
    return i;
}

function mandelbrot(c: Complex, maxIterations: number): number {
    let z = new Complex(0, 0);
    return iterateF(z, c, maxIterations)
}

在此,我先忽略具体渲染图像的实现细节,毕竟这部分有点长,并且也不是那么重要。 当我们把平面上的每个点都迭代一遍,我们就可以得到一个默认的Mandelbrot set图像了。

缩放

为了观察Mandelbrot set的边界,我添加了可交互的组件,以此来调整偏移值和缩放比例。

其中, scale, X offset, 以及Y offset都比较直观。所有这些值的步长都可以通过系数和幂来控制,默认的步长是0.1。

因为我把迭代次数映射到了色相,使颜色的差异会很小,所以我引入了colorScale来增强颜色变化。

const { r, g, b } = hslToRgb(iterations * colorScale, 100, 50);

Julia set

当我读到Julia set的定义时,我发现它跟Mandelbrot set几乎一摸一样。 在Mandelbrot set中,zz的初始值是(0,0)(0,0),然后我们迭代不同的常数cc。 在Julia set中,我们固定常数cc的初始值,然后迭代不同的起始值zz

z = new Complex(re, im)
if (e.data.fnType === "mandelbrot") {
    fn = (c: Complex, maxIterations: number) => {
        return iterateF(z, c, maxIterations) 
    }
} else if (e.data.fnType === "julia") {
    fn = (c: Complex, maxIterations: number) => {
        return iterateF(c, z, maxIterations) 
    }
} else {
    fn = mandelbrot
}

其他

还有一些其他因素会影响Mandelbrot set最终输出的图像,或许我会在将来再更新到这篇文章中。