考虑函数f(z)=z^2-0.75。固定z0的值后,我们可以通过不断地迭代算出一系列的z值:z1=f(z0), z2=f(z1), z3=f(z2), …。比如,当z0 = 1时,我们可以依次迭代出:
z1 = f(1.0) = 1.0^2 – 0.75 = 0.25
z2 = f(0.25) = 0.25^2 – 0.75 = -0.6875
z3 = f(-0.6875) = (-0.6875)^2 – 0.75 = -0.2773
z4 = f(-0.2773) = (-0.2773)^2 – 0.75 = -0.6731
z5 = f(-0.6731) = (-0.6731)^2 – 0.75 = -0.2970
…
可以看出,z值始终在某一范围内,并将最终收敛到某一个值上。
但当z0=2时,情况就不一样了。几次迭代后我们将立即发现z值最终会趋于无穷大:
z1 = f(2.0) = (2.0)^2 – 0.75 = 3.25
z2 = f(3.25) = (3.25)^2 – 0.75 = 9.8125
z3 = f(9.8125) = (9.8125)^2 – 0.75 = 95.535
z4 = f(95.535) = (95.535)^2 – 0.75 = 9126.2
z5 = f(9126.2) = (9126.2)^2 – 0.75 = 83287819.2
…
经过计算,我们可以得到如下结论:当z0属于[-1.5, 1.5]时,z值始终不会超出某个范围;而当z0小于-1.5或大于1.5后,z值最终将趋于无穷。
现在,我们把这个函数扩展到整个复数范围。对于复数z0=x+iy,取不同的x值和y值,函数迭代的结果不一样:对于有些z0,函数值约束在某一范围内;而对于另一些z0,函数值则发散到无穷。由于复数对应平面上的点,因此我们可以用一个平面图形来表示,对于哪些z0函数值最终趋于无穷,对于哪些z0函数值最终不会趋于无穷。我们用深灰色表示不会使函数值趋于无穷的z0;对于其它的z0,我们用不同的颜色来区别不同的发散速度。由于当某个时候|z|>2时,函数值一定发散,因此这里定义发散速度为:使|z|大于2的迭代次数越少,则发散速度越快。这个图形可以编程画出。和上次一样,我用Pascal语言,因为我不会C的图形操作。某个MM要过生日了,我把这个自己编程画的图片送给她^_^
{$ASSERTIONS+}
uses graph;
type
complex=record
re:real;
im:real;
end;
operator * (a:complex; b:complex) c:complex;
begin
c.re := a.re*b.re - a.im*b.im;
c.im := a.im*b.re + a.re*b.im;
end;
operator + (a:complex; b:complex) c:complex;
begin
c.re := a.re + b.re;
c.im := a.im + b.im;
end;
var
z,c:complex;
gd,gm,i,j,k:integer;
begin
gd:=D8bit;
gm:=m640x480;
InitGraph(gd,gm,'');
Assert(graphResult=grOk);
c.re:=-0.75;
c.im:=0;
for i:=-300 to 300 do
for j:=-200 to 200 do
begin
z.re:=i/200;
z.im:=j/200;
for k:=0 to 200 do
begin
if sqrt(z.re*z.re + z.im*z.im) >2 then break
else z:=(z*z)+c;
end;
PutPixel(i+300,j+200,k)
end;
readln;
CloseGraph;
end.
代码在Windows XP SP2,FPC 2.0下通过编译,麻烦大家帮忙报告一下程序运行是否正常(上次有人告诉我说我写的绘图程序不能编译)。在我这里,程序运行的结果如下:
这个美丽的分形图形表现的就是f(z)=z^2-0.75时的Julia集。考虑复数函数f(z)=z^2+c,不同的复数c对应着不同的Julia集。也就是说,每取一个不同的c你都能得到一个不同的Julia集分形图形,并且令人吃惊的是每一个分形图形都是那么美丽。下面的六幅图片是取不同的c值得到的分形图形。你可能不相信这样一个简单的构造法则可以生成这么美丽的图形,这没什么,你可以改变上面程序代码中c变量的值来亲自验证。
c = 0.45, -0.1428
c = 0.285, 0.01
c = 0.285, 0
c = -0.8, 0.156
c = -0.835, -0.2321
c = -0.70176, -0.3842
类似地,我们固定z0=0,那么对于不同的复数c,函数的迭代结果也不同。由于复数c对应平面上的点,因此我们可以用一个平面图形来表示,对于某个复数c,函数f(z)=z^2+c从z0=0开始迭代是否会发散到无穷。我们同样用不同颜色来表示不同的发散速度,最后得出的就是Mandelbrot集分形图形:
前面说过,分形图形是可以无限递归下去的,它的复杂度不随尺度减小而消失。Mandelbrot集的神奇之处就在于,你可以对这个分形图形不断放大,不同的尺度下你所看到的景象可能完全不同。放大到一定时候,你可以看到更小规模的Mandelbrot集,这证明Mandelbrot集是自相似的。下面的15幅图演示了Mandelbrot集的一个放大过程,你可以在这个过程中看到不同样式的分形图形。
网上可以找到很多小程序实现Mandelbrot集的放大过程。把上面给出的代码改一改,你也可以写出一个这样的程序来。
Update:2011 年 8 月 31 日,我对这个话题做了更进一步的讨论 http://www.matrix67.com/blog/archives/4570
很难坐沙发,现在先坐一下
c语言如何绘图呢?
刚想说RP这么好有沙发,谁知道还是没有,晕
很漂亮!能运行,XP SP2,FPC 1.0.6
实在是太强了!这么漂亮!由衷的对数学产生一种敬仰。。。
怎样放大?把代码写出来好么?我没学过operator这种东西,看不太懂你的源程序。
newbee!
orz the Math
用lazarus编译似乎应该改为smallint………
犹如醍醐灌顶,太感谢这个论坛了!
我以前只知道固定z0的值,却不知道把z0作为复平面!
总之太感谢了!!!!!!
LS不要说这是个论坛,知道不?
知道不?知道不?知道不?
“对于有些z0,函数值约束在某一范围内;而对于另一些z0,函数值则发散到无穷。”还有第三种情况,f[x]=-x,当z0=1时,会不满足上面的两个条件
刚才还看了Mandelbrot集和Julia集的关系,前者如果是本书的话,后者就是其中的一页,就是说每个Mandelbrot集放大后都会成为一个Julia集……
我只是现学现卖,大牛不要BS我……
回复:函数只能是x^2+c的形式
狂汗中,大牛竟然能玩出这种东西
k的颜色怎么调,有表吗?
graph可以支持16bit及800*600吗?
像发霉一样的图片……我不觉得漂亮的说……
请问,你是怎么把图形拷下的啊??
用什么方法,请快回复为谢!谢谢!谢谢!谢谢
回复:截屏啊
(楼上有点冷……)
太神奇了。。
15楼只会说,有本事搞几幅新鲜的……
在FP2.1.4,Windows vista home basic 下编译没通过啊……
混沌学的初级原理竟然……
实在美丽,妙不可言
为什么我做出来颜色一点都不好看????图形一样的。用你的程序。
我用fp 2.2.4
好象不能编译的原因的是因为smallint的缘故..
如果遇到不能编译的编译器按照提示把相应的integer类型改成
smallint应该就可以…
————————————
..以前还没用过Pascal画过图呢…
请问有无想过做penrose拼砌的东西……本人学艺不精,CAD不上手,想问下大牛
FP死活找不到GRAPH单元
M集里面的小M集只是类似,细节是不一样的。
這裡有徒手畫Mandelbrot set的教學
http://www.wikihow.com/Plot-the-Mandelbrot-Set-By-Hand
matrix大神,后面那些图是不是你画的啊,放大那么多次应该要使用高精度才能进行计算吧,并且颜色也太专业了啊。
我玩了很多年Mandelbrot集了。
为什么我这里能跑出来但是颜色不一样?求速回……
FPC 2.4.2
楼主这个是用什么软件做的哦
大大,那个Z0的取值范围是怎么确定的呀?跪求!
请问作者的大名,可以吗
应该叫碎片几何集。
Thank you for the auspicious writeup. It in truth used to
be a entertainment account it. Look complicated to more introduced agreeable from you!
However, how can we keep up a correspondence?