Board logo

标题: [技术讨论] [Perl][分形艺术]Julia集的绘制、缩放 [打印本页]

作者: 523066680    时间: 2015-8-3 19:33     标题: [Perl][分形艺术]Julia集的绘制、缩放

计算公式和方法我是直接抄Matrix67 数学笔记里面的
神奇的分形艺术(四):Julia集和Mandelbrot集
本来昨天还可以访问,今天不知为何404了

因为这套公式是直接按理论的方法计算,没有优化,运行消耗不少,所以直接就改小了生成图像的尺寸。
按 4 6 8 2 左右上下移动, 按5放大 按0缩小

运行环境:ActivePerl, V5.16, for windows
依赖的库:OpenGL  没安装的可以再activeperl的环境下执行:ppm install OpenGL
  1. use IO::Handle;
  2. use OpenGL qw/ :all /;
  3. use OpenGL::Config;
  4. use Time::HiRes 'sleep';
  5. use feature 'state';
  6. STDOUT->autoflush(1);
  7. my ($re, $im);
  8. #my @c = ( 0.3, 0 ); #云
  9. #my @c = ( 0.279, 0.0 );
  10. my @c = ( 0.316, -0.033 );
  11. my @z = ();
  12. our $dtx = 200;
  13. our $dty = 100;
  14. our $moveDT = 30;
  15. our $movex = 0;
  16. our $movey = 0;
  17. our $left;
  18. our $right;
  19. our $bottom;
  20. our $top;
  21. our $scale = 1;
  22. our $depth = 100;
  23. &Main();
  24. sub display
  25. {
  26.     my ($i, $j, $k);
  27.     $left   = -$dtx/2 + $movex;
  28.     $right  = $dtx/2 + $movex;
  29.     $bottom = -$dty/2 + $movey;
  30.     $top    = $dty/2 + $movey;
  31.     glClear(GL_COLOR_BUFFER_BIT);
  32.     glBegin(GL_POINTS);   
  33.     for ($i = $left; $i < $right; $i += 1)
  34.     {
  35.         for ($j = $bottom; $j < $top; $j += 1)
  36.         {
  37.             ($re, $im) = (
  38.                 $i / ($dty *$scale),
  39.                 $j / ($dty *$scale),
  40.             );
  41.             
  42.             for ($k=0; $k <= $depth; $k++)
  43.             {
  44.                 $xre = $re * $re;
  45.                 $xim = $im * $im;
  46.                 if ( ($xre + $xim ) > 4 )
  47.                 {
  48.                     last;
  49.                 }
  50.                 else
  51.                 {
  52.                     ($re, $im) = (
  53.                         $xre - $xim + $c[0],
  54.                         $re * $im * 2  + $c[1],
  55.                     );
  56.                 }
  57.             }
  58.             
  59.             glColor3f( colors($k, 33.3) );
  60.             glVertex3f( $i - $movex, $j - $movey, 0.0);
  61.         }
  62.     }
  63.    
  64.     glEnd();
  65.     glutSwapBuffers();
  66. }
  67. sub colors
  68. {
  69.     my ($value, $limit) = (shift, shift);
  70.     my ($R, $G, $B);
  71.     if ($value > $limit) {
  72.         $R = 0.0;
  73.         $value -= $limit;
  74.     } else {
  75.         $R = $value / $limit;
  76.     }
  77.     if ($value > $limit ) {
  78.         $G = 0.0;
  79.         $value -= $limit;
  80.     } else {
  81.         $G = $value / $limit;
  82.     }
  83.     $B = $value % $limit /$limit;
  84.     return ($R, $G, $B);
  85. }
  86. sub init
  87. {
  88.     glClearColor(0.0, 0.0, 0.0, 1.0);
  89.     glPointSize(1.0);
  90. }
  91. sub idle
  92. {
  93.     sleep 0.01;
  94.     glutPostRedisplay();
  95. }
  96. sub Reshape
  97. {
  98.     my $half = 250.0;
  99.     glViewport(0.0,0.0,500.0,500.0);
  100.     glMatrixMode(GL_PROJECTION);
  101.     glLoadIdentity();
  102.     glOrtho(-$half, $half,-$half, $half,0.0,200.0);
  103.     glMatrixMode(GL_MODELVIEW);
  104.     glLoadIdentity();
  105.     gluLookAt(0.0,0.0,100.0,0.0,0.0,0.0, 0.0,1.0,100.0);
  106. }
  107. sub hitkey
  108. {
  109.     my $keychar = lc(chr(shift));
  110.     if ($keychar eq 'q') {
  111.         glutDestroyWindow($WinID);
  112.     }
  113.     if ($keychar eq '4') {
  114.         $movex -= 50;
  115.         glutPostRedisplay();
  116.     } elsif ($keychar eq '6') {
  117.         $movex += $moveDT;
  118.         glutPostRedisplay();
  119.     } elsif ($keychar eq '8') {
  120.         $movey += $moveDT;
  121.         glutPostRedisplay();
  122.     } elsif ($keychar eq '2') {
  123.         $movey -= $moveDT;
  124.         glutPostRedisplay();
  125.     } elsif ($keychar eq '5') {
  126.         $scale *= 1.1;
  127.         $movex *= 1.1;
  128.         $movey *= 1.1;
  129.         glutPostRedisplay();
  130.         
  131.     } elsif ($keychar eq '0') {
  132.         $scale /= 1.1;
  133.         $movex /= 1.1;
  134.         $movey /= 1.1;
  135.         glutPostRedisplay();
  136.         
  137.     }
  138. }
  139. sub Main
  140. {
  141.     glutInit();
  142.     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );
  143.     glutInitWindowSize(500, 500);
  144.     glutInitWindowPosition(1,1);
  145.     our $WinID = glutCreateWindow("title");
  146.     &init();
  147.     glutDisplayFunc(\&display);
  148.     glutReshapeFunc(\&Reshape);
  149.     glutKeyboardFunc(\&hitkey);
  150.     glutIdleFunc(\&idle);
  151.     glutMainLoop();
  152. }
复制代码

作者: 523066680    时间: 2015-8-3 22:14

本帖最后由 523066680 于 2015-8-3 22:43 编辑

原来Matrxi67数学笔记上面的 PASCAL 代码相当直观,复制过来供参考。
还要百度有快照,关于公式的说明:

神奇的分形艺术(四):Julia集和Mandelbrot集 百度快照


代码中的 i j 其实分别代表窗口上的 x 像素位置 和 y 像素位置
取值范围分别为 [-300,300] [-200, 200]
然后将 i/200, j/200 作为复数Z的实部 和 虚部进行代入计算 -> 其实单独写了个循环 k = 1 到 200 迭代试算(判断方面参考页面)
根据k的大小设置颜色深度,以i为x坐标, j为y坐标进行点绘

环境搭建:安装free pascal 编译器 win32版 (64位版本不含 graph 库)
编译Pascal程序:建议使用命令执行 fpc source.pp 进行编译。自带那个编辑器界面乱码……

http://sourceforge.net/projects/freepascal/files/
  1. {$ASSERTIONS+}
  2. uses graph;
  3. type
  4.    complex=record
  5.       re:real;
  6.       im:real;
  7.    end;
  8. operator * (a:complex; b:complex) c:complex;
  9. begin
  10.    c.re := a.re*b.re - a.im*b.im;
  11.    c.im := a.im*b.re + a.re*b.im;
  12. end;
  13. operator + (a:complex; b:complex) c:complex;
  14. begin
  15.    c.re := a.re + b.re;
  16.    c.im := a.im + b.im;
  17. end;
  18. var
  19.    z,c:complex;
  20.    gd,gm,i,j,k:integer;
  21. begin
  22.    gd:=D8bit;
  23.    gm:=m640x480;
  24.    InitGraph(gd,gm,'');
  25.    Assert(graphResult=grOk);
  26.    c.re:=-0.75;
  27.    c.im:=0;
  28.    for i:=-300 to 300 do
  29.    for j:=-200 to 200 do
  30.    begin
  31.       z.re:=i/200;
  32.       z.im:=j/200;
  33.       for k:=0 to 200 do
  34.       begin
  35.          if sqrt(z.re*z.re + z.im*z.im) >2 then break
  36.          else z:=(z*z)+c;
  37.       end;
  38.       PutPixel(i+300,j+200,k)
  39.    end;
  40.    readln;
  41.    CloseGraph;
  42. end.
复制代码

作者: happy886rr    时间: 2016-4-24 20:37

回复 2# 523066680
我发现matrix67笔记的女作者数学小宇宙异常强大,居然能导出那么美的图形。
作者: codegay    时间: 2016-4-24 20:44

吓尿了,我以为是julialang
作者: happy886rr    时间: 2016-4-24 21:01

回复 4# codegay
julia,python直接就能计算复数,当然可以用更少代码实现。但是我只会用logo语言绘图,就是那种海龟。
作者: codegay    时间: 2016-4-24 21:10

回复 5# happy886rr


    都是用现成的库。难度应该也不会太大。
作者: 523066680    时间: 2016-4-26 16:58

本帖最后由 523066680 于 2016-5-30 18:20 编辑

回复 6# codegay


    要做动态效果需要高效率计算,最好上渲染语言(GLSL/HLSL)

(动图好像无效?

作者: 523066680    时间: 2016-4-26 17:04

回复 3# happy886rr


    我记得他有头像是男的啊
作者: happy886rr    时间: 2016-4-27 12:36

回复 8# 523066680
他们是一对夫妇,共同爱好数学,生了两男孩,有些文章是那女的写的,虽然个别数学观点是错的,但是图画的不错。
作者: codegay    时间: 2016-4-27 13:30

回复 9# happy886rr


    。。。。。。。。可是找他找女朋友结婚生孩子只是最近几年的事情。。。至少是2011年后的事情。
作者: 523066680    时间: 2016-4-27 15:20

回复 9# happy886rr


    哇塞原来有这么多内幕,学习了
作者: 523066680    时间: 2016-10-27 21:14

本帖最后由 523066680 于 2016-10-27 21:15 编辑

C

作者: Bella    时间: 2016-10-27 21:38

本帖最后由 Bella 于 2016-10-28 22:08 编辑

回复 12# 523066680


    这效果酷炫, 每天看终端就是这感觉, 眼睛受不了有残影




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2