Mandelbrot

来源:百度文库 编辑:超级军网 时间:2024/05/04 05:15:24
总览
test.jpg
上部放大
b.jpg
继续放大
c.jpg
继续放大
d.jpg
某个毛毛的细节
e.jpg
左侧的主沟
f.jpg总览
test.jpg
上部放大
b.jpg
继续放大
c.jpg
继续放大
d.jpg
某个毛毛的细节
e.jpg
左侧的主沟
f.jpg
这么性感的美图居然没人回,太伤心鸟[:a5:]!
自己顶一下!
看看那丰满的身躯,那纤细的腰肢,那性感的汗毛[:a2:]:D。


a.jpg
再附赠一张黑化宽屏桌面。1280*800,笔记本正好。

a.jpg
再附赠一张黑化宽屏桌面。1280*800,笔记本正好。
j.png
上面最大的瘤的三叉刺,可见其丰富的细节。


k.png
三叉刺的交叉部分的放大。已经达到Perl默认浮点数的最高精度,无法再放大。其实应当有三道黑线,因为整个不发散的区域是连通的,但精度不够,没有采样到相应的点上。
宽、高分别为:8e-15,6e-15
位置在:-0.1010963638456222+0.9562865108091419i
这是什么东西?:L
尼米兹 发表于 2009-5-4 20:24
终于有人回了[:a5:] 。
设定如下复数数列:
C0=某指定值
C第n个=C第n-1个^2+C0
考虑每项的模。

考虑某复数平面上某点x+yi带入C0,如果当n->inf时,令那个数列的模不发散,就把点涂成黑色。

实际计算时,不存在某种算法判定数列是否发散。使用如下方法判定:
如果数列某项的模大于1+根号2,那么接下来必定发散。
如果数列在n项内都没有大于1+根号2,认为其不发散。n取值越大,图像细节越接近真实情况。



定义  曼德布洛特集合(Mandelbrot set)是在复平面上组成分形的点的集合。Mandelbrot集合可以用复二次多项式f(z)=z^2+c来定义。

  其中c是一个复参数。对于每一个c,从z=0开始对f(z)进行迭代

  序列 (0, f(0), f(f(0)), f(f(f(0))), .......)的值或者延伸到无限大,或者只停留在有限半径的圆盘内。

  曼德布洛特集合就是使以上序列不延伸至无限大的所有c点的集合。

  从数学上来讲,曼德布洛特集合是一个复数的集合。一个给定的复数c或者属于曼德布洛特集合M,或者不是。

  图例:如果c点属于曼德布洛特集合M则为黑色,反之为白色

计算的方法  曼德布洛特集合一般用计算机程序计算。对于大多数的分形软件,例如Ultra fractal,内部已经有了比较成熟的例子。下面的程序是一段伪代码,表达了曼德布洛特集合的计算思路。

  For Each z0 in Complex

  repeats = 0

  z=z0

  Do

  z=z^2+z0

  repeate = repeats+1

  Loop until abs(z)>Bailout or repeats >= MaxRepeats

  If repeats >= MaxRepeats Then

  Draw z0,Black

  Else

  Draw z0,f(z,z0,Repeats) 'f返回颜色

  End If

  Next
我自己用perl写的类
#!/usr/bin/perl


package Mandelbrot;
use strict;
use Data::Dump qw/dump/;
use BMPWrite;

sub new {
        my ($invo,%arg)=@_;
        my $class=ref $invo || $invo;
        my $data={
                -width=>4,
                -height=>3,
                -screen_rate=>600, # vertical resolution
                -center_x=>0,
                -center_y=>0,
                -color0=>[0,0,0x7f],
                -color1=>[0xff,0xff,0xff],
                -color2=>[0,0,0],
                -iterate=>50
        };
        return bless $data,$class;
}

sub width {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-width}=$value;
        }
        return $self->{-width};
}

sub height {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-height}=$value;
        }
        return $self->{-height};
}

sub screen_rate {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-screen_rate}=$value;
        }
        return $self->{-screen_rate};
}

sub screen_height {
        my $self=shift;
        return int $self->screen_rate;
}
sub screen_width {
        my $self=shift;
        return int $self->screen_rate*$self->width/$self->height;
}

sub center_x {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-center_x}=$value;
        }
        return $self->{-center_x};
}

sub center_y {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-center_y}=$value;
        }
        return $self->{-center_y};
}

sub color0 {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-color0}=$value;
        }
        return $self->{-color0};
}

sub color1 {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-color1}=$value;
        }
        return $self->{-color1};
}

sub color2 {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-color2}=$value;
        }
        return $self->{-color2};
}

sub iterate {
        my($self,$value)=@_;
        if(defined $value) {
                $self->{-iterate}=$value;
        }
        return $self->{-iterate};
}

sub calculate_mask {
        my $self=shift;
        my $y_count_limit=$self->screen_rate;
        my $x_count_limit=$y_count_limit*$self->width/$self->height;
        my $init_x=$self->center_x-$self->width/2;
        my $init_y=$self->center_y-$self->height/2;
       
        my @data;
        for (my $y_count=0; $y_count<$y_count_limit; $y_count++) {
                my $y=$init_y+$self->height*$y_count/$y_count_limit;
                my @line_data;
                print "$y_count: $y\n";
                for (my $x_count=0; $x_count<$x_count_limit; $x_count++) {
                        my $x=$init_x+$self->width*$x_count/$x_count_limit;
                        push @line_data,$self->_calculate_point($x,$y);
                }
                unshift @data,[@line_data];
        }
       
        return @data;
}

sub draw_table_file {
        my($self,$file_out,$dataref)=@_;
        open OUT,">$file_out";
        my @data=@$dataref;
        foreach my $curr (@data) {
                print OUT join("\t",@$curr),"\n";
        }
        close OUT;
}

sub draw_ps {
        my($self,$file_out)=@_;
        my @data=$self->calculate_mask;
        open OUT,">$file_out";
        print OUT scalar(@{$data[0]})," ",scalar(@data)," 8 [ 1 0 0 1 0 0 ]\n";
        print OUT "{ <\n";
       
        while (my $line=pop @data) {
                foreach my $curr (@$line) {
                        my($r,$g,$b)=$self->_define_color($curr);
                        printf OUT "%.2x%.2x%.2x",$r,$g,$b;
                }
                print OUT "\n";
        }
        print OUT "> }\n";
        print OUT "false 3 colorimage\n";
        close OUT;
}

sub draw_bmp {
        my($self,$file_out)=@_;
       
        my @data=$self->calculate_mask;
        #$self->draw_table_file($file_out.".log",\@data);
        my $bmp=BMPWrite->new();
        $bmp->{-data}=[[[0,0,0]]];
        #print "draw_bmp: data: ",dump($bmp->{-data}),"\n";
        $bmp->width(scalar(@{$data[0]}));
        $bmp->height(scalar(@data));
        #print "draw_bmp: data: ",dump($bmp->{-data}),"\n";
        #exit;
       
        print "generating bmp..\n";
        my $y=0;
        while (my $line=pop @data) {
                my $x=0;
                foreach my $curr (@$line) {
                        my($r,$g,$b)=$self->_define_color($curr);
                        #print "$curr => $r $g $b\n";
                        $bmp->pixel($y,$x,[$r,$g,$b]);
                }continue{$x++;}
        }continue{$y++};
        print "complete\n";
        $bmp->write($file_out);
}

sub _calculate_point { # returns iterate time
        my($self,$initx,$inity)=@_;
        #print "$initx,$inity\n";
        my($x,$y)=($initx,$inity);
        my $it_count=0;
        my($tmpx,$tmpy);
        while ($x**2+$y**2 < 4) {
                #print "$x,$y\n";
                $tmpx=$x;
                $tmpy=$y;
                $x=$tmpx**2-$tmpy**2+$initx;
                $y=2*$tmpx*$tmpy+$inity;
                $it_count++;
                if ($it_count>=$self->iterate) {last;}
        }
        return $it_count;
}

sub _define_color {
        my($self,$it)=@_;
        my $max=$self->iterate;
        if ($it==$max) {
                return @{$self->color2};
        }
        else {
                my $c_rate=$it/$max;
                my($r0,$g0,$b0)=@{$self->color0};
                my($r1,$g1,$b1)=@{$self->color1};
                my $r=int $c_rate*$r1+(1-$c_rate)*$r0;
                my $g=int $c_rate*$g1+(1-$c_rate)*$g0;
                my $b=int $c_rate*$b1+(1-$c_rate)*$b0;
                return ($r,$g,$b);
        }
}
1;
呼叫斑竹加分:lol


想起了在昏暗的小台灯下,抱着pentium机傻乐的时光。

楼主我顶你!自己做的?!


哦,楼主自己做的,不错!
不是所有人都觉得数学有快感,不过哪快感确实很爽。虽然和高潮来自大脑不同分区,但是一瞬间曾经的感觉,我相信多巴胺信使分泌量是一样的,当然皮层区还是清醒的。{:3_97:}

想起了在昏暗的小台灯下,抱着pentium机傻乐的时光。

楼主我顶你!自己做的?!


哦,楼主自己做的,不错!
不是所有人都觉得数学有快感,不过哪快感确实很爽。虽然和高潮来自大脑不同分区,但是一瞬间曾经的感觉,我相信多巴胺信使分泌量是一样的,当然皮层区还是清醒的。{:3_97:}
wenci 发表于 2009-5-5 16:29
主要是有装B的快感:D :victory:
分形哇,很漂亮。还记得黑客帝国不,其中就有一个分形出现,跟你的很像啊
多谢版主:lol