函数也可以如此美丽——Julia集的分形艺术微博:@月绒兔子前言大家在高中的时候都学过解析函数吧?说解析函数是不是有点显得太高端了?那好,给你一个y=x的函数,在XY坐标系上画出这个函数的图像。
别告诉我你不会啊,这可是拿脚后跟都能画出来的图像啊。
闲话不多说了。
首先,先声明下此文并不是给大家讲数学的,也不是专门给理工科童鞋看的。
此文的目的就是想让大家知道,有那么一个函数,她是如此的奇幻如此的美丽多变,就像她的名字一样—Julia。
然后我们用HTML5的canvas来召唤她。
先来几张Julia的芳容欣赏下:没错,以上四个图片不是电脑桌面,但是它确实Julia集合(Julia Set)所描绘的抽象艺术。
Julia集简介我是在一门叫做“高等统计物理”的课程上认识到Julia集的。
虽然她的图像非常绚丽多姿,但其实她的真身非常简单,简单到你不敢想象:f(z)=z^2+C其中,z^2表示z的平方,z和C均为复数(复习一下:复数就是a+ib,a为实部,b为虚部,i就是表示虚部的部分)。
然后我们做以下的迭代:Z1=f(z0)Z2=f(z1)Z3=f(z2)Z4=f(z3)…那么当Z0=0,C=0.5时Z1=0^2+0.5=0.5Z2=0.5^2+0.5=0.75Z3=0.75^2+0.5=1.0625Z4=1.0625^2+0.5=1.62890625Z5=1.62890625^2+0.5=3.653355…Z6=Z5^2+0.5=14.346860796…最终Zn趋于无限大。
同理,如果令Z0等于另一个值时,有可能会出现最终Zn收敛于某一值(无限趋近于某一个值),也有可能趋近无穷大,或者趋近无穷小(负值)。
Julia集绘制原理上面的简介说明了其实Julia集就是一个迭代函数而已,那么,这么美丽的图像是怎么画出来的呢?其实很简单,刚才我有提到过,z和C都是复数,C是常量。
所以,z=x+iy,C=a+ib,图像是以x为横坐标,y为纵坐标绘制的。
这么说来,只要随便改变a和b的值,就会出现不同的图案了。
那么图像中颜色是根据什么来的呢?我们从画布左上角第一个像素(x=0,y=0)开始,这个像素所代表的物理意义就是,当z=0+i0(也就是z=0)时,进行Zn的迭代计算。
我们预先设置一个阀值k(例如k=4),当计算到Z10的时候,发现Z10的模大于k了(|Z10|>k),就说明在迭代到第10次的时候发散了。
依此类推,如果是计算到Z88的时候|Z88|>k了,就说明迭代到第88次的时候发散了。
这时候你就可以按照你的口味来了,你可以设置为发散的越慢(迭代次数越多)颜色越深,发散的越快(迭代次数越少)颜色越浅。
当然也可以用冷暖色系来表示。
找到形成发散的迭代次数,就可以结束迭代运算了。
当然,有一点是要注意的,这个迭代在计算到很高阶的时候运算量可是会很大的哦,所以一定要设置一个迭代次数的最大值,比如,如果再迭代到300次的时候,|Zn|还没有大于阈值k,那就认为这个点永远不会发散了(可以叫做收敛点),直接停止迭代运算。
这点的颜色就按迭代最大值时对应的颜色值来填充。
第一个点的绘制原理就是酱紫。
下面就是要遍历所有的点,按照同样的方法让计算机去计算喽。
如果你的画布是800x800,那就需要从(x=0,y=0)一直遍历到(x=800,y=800),一共是800x800=640000个点。
如果你对你的电脑运算能力有信心的话,就可以利用Julia集绘制高分辨的HD桌面壁纸喽!Julia集的魅力所在学术界对于Julia集的研究非常广泛,学者们深深被这个集合的美丽和规律所吸引。
除了她的多变和美丽外,还有一个神奇的地方(不要跟太多人讲哦),就是她的分形艺术(fractal art)。
分形所呈现的无穷玄机和美感引发人们不断的探索。
即使不懂得其中深奥的数学哲理,也会为之感动。
分形把科学与艺术无缝的结合到了一起,使得枯燥的数学不再是抽象的哲理,而是一种具体的视觉感受,一种神奇的艺术创作。
分形艺术体现了很多传统美学的标准,例如平衡、和谐、对称等,它的结构饱满而又不杂乱,混乱中有秩序,统一中有丰富,能够给人带来强烈的视觉冲击力和审美快感。
分形艺术有以下三个基本特征:1.自相似性对几何对象某个局部放大后,其与放大前的整体图像相似2.极不规则很多分形图案不能用简单的几何图形图形去描述。
3.无限精细对几何对象任一个细节进行放大,无论放大多少倍,不但不会丢失细节,反而会看到更精细的细节来拿Julia集形象的说明一下以上的特点:以上一系列的图可以看到,对Julia集图像的任一个细节进行一次次的放大,可以无限的看到越来越精细的画面,可谓是柳暗花明又一村,欲穷千里目,更放大一倍!Julia集的Web前端实现只要清楚了Julia集的数学运算过程,利用HTML5 canvas可以很轻松的实现Julia的绘制。
首先要写一个复数运算类//复数类var Complex = function(x,y){this.x = x;this.y = y;//模this.modes = Math.sqrt(x*x+y+y);//字符串显示this.toStr = x+","+y;//加this.add= function(z) { return new Complex( this.x+z.x, this.y+z.y); }//减this.sub= function(z) { return new Complex( this.x-z.x, this.y-z.y); }//乘this.multiply= function(z) //乘{return new Complex( this.x*z.x- this.y*z.y, this.x*z.y+ this.y*z.x);}}还有一个将迭次数转换为对应RGB颜色的函数://数值转RGB(仅为deom,有待狠狠优化)function num2rgb(num){num = num * 20;if(num < 255){return num+",0,0";}else if(num < 511){return "255,"+(num-255)+",0";}else if(num < 767){return (255-(num-511))+",255,0";}else if(num < 1023){return "0,255,"+(num-767);}else if(num < 1279){return "0,"+(255-(num-1023))+",255";}else if(num < 1535){return (num-1279)+",0,255";}}下面就是Julia绘制的函数了:function drawjulia(){var x = parseFloat(document.getElementById("val_x").value);var y = parseFloat(document.getElementById("val_y").value);var canvas=document.getElementById("julia");var cxt=canvas.getContext("2d");cxt.clearRect(0,0,500,300);var colorset = "#fff";var nColor = 0;var nRed = 0;var nGreen = 0;var nBlue = 0;var zn = new Complex(0,0);var c = new Complex(x,y);var width = 250;var height = 150;for(var i=-1*width;i<=width;i++){for(var j=-1*height;j<=height;j++){zn.x = i/width;zn.y = j/height;for(nColor = 0; nColor<=25;nColor++){if((zn.x * zn.x + zn.y * zn.y) > 4){break;}else{zn = zn.multiply(zn);zn = zn.add(c);}}colorset = "rgb("+num2rgb(nColor)+")";cxt.strokeStyle = colorset;cxt.beginPath();cxt.moveTo(i+width, j+height);cxt.lineTo(i+width, j+height+1);cxt.stroke();cxt.closePath();}}}在页面上输入参数后,点击“绘图”按钮,经过浏览器的暂时假死,便可以看到图像啦(颜色有待优化,比较山寨…)当然,有编程经验的同学可以试着用其他语言编写下,可能性能会更好一些。
我用C#尝试了下,效果还不错:分形图案欣赏其他参考Julia集:/wiki/Julia_setC#实现Julia集:/betaq/archive/2010/05/24/1742872.html 分形艺术:/view/683655.htm。