搞了一天,终于全部搞定了,久久惊叹于分形的美而不能自拔……

先来简单介绍下Julia集和Mandelbrot集:(来自这里)

曼德勃罗特(Mandelbrot)集是人类有史以来做出的最奇异,最瑰丽的几何图形.曾被称为“上帝的指纹”。

这个点集均出自公式:Zn+1=(Zn)^2+C,

  这是一个迭代公式,式中的变量都是复数.这是一个大千世界,从他出发可以产生无穷无尽美丽图案,他是曼德勃罗特教授在二十世纪七十年代发现的.你看上图中,有的地方象日冕,有的地方象燃烧的火焰,只要你计算的点足够多,不管你把图案放大多少倍,都能显示出更加复杂的局部.这些局部既与整体不同,又有某种相似的地方,好像着梦幻般的图案具有无穷无尽的细节和自相似性.曼德勃罗特教授称此为"魔鬼的聚合物".为此,曼德勃罗特在1988年获得了"科学为艺术大奖".

更详尽的解释请看维基百科。

好了,让我们边讲代码边体会吧:我们要做这样一个程序,它

  1. 可以快速计算分形
  2. 可以彩色显示
  3. 可以鼠标画矩形放大
  4. 可以将观察过程的图片存起来

1、首先,做一些准备工作:

#include <cv.h>
#include <highgui.h>
#include <cxcore.h>#define IMG_8UB(img,x,y) ((uchar*)(img->imageData + img->widthStep * (y)))[3 * (x)]
#define IMG_8UG(img,x,y) ((uchar*)(img->imageData + img->widthStep * (y)))[3 * (x) + 1]
#define IMG_8UR(img,x,y) ((uchar*)(img->imageData + img->widthStep * (y)))[3 * (x) + 2]
#define IMG8U(img,x,y) ((uchar*)(img->imageData + img->widthStep * (y)))[(x)] CvPoint pt1 = {-1,-1};//两个用来记录鼠标点击和放松的点
CvPoint pt2 = {-1,-1};
IplImage* fractal;
IplImage* fcopy;//用来画矩形
int width = 600;//图像宽和高
int height = 400;
double XMax = 2.5;//复平面的最大坐标
double XMin = -2.5;
double YMax = 2.5;
double YMin = -2.5;#define MAX_COLOR 256//用来记录配色,毕竟黑白的不是那么好看
int B[MAX_COLOR];
int G[MAX_COLOR];
int R[MAX_COLOR];struct Complex//复数
{double real;double img;
};char* name[100];//即时输出观察时候的图片的名字
int fileIndex = 0;//标号

2.初始化文件

char* itoa(int value)
{char* tmp = (char*)calloc(11,sizeof(char));char reverse[15];int index = 0;do{reverse[index++] = value % 10 + '0';value /= 10;}while(value);int size = index - 1;while(index--){tmp[size - index] = reverse[index];}tmp[++size] = '.';tmp[++size] = 'j';tmp[++size] = 'p';tmp[++size] = 'g';tmp[++size] = '\0';return tmp;
}
void initFileName()//直接用数字命名图片了
{for(int i = 0;i < 100;i++)name[i] = itoa(i);
}

3初始化图片彩色像素库

分形配色是最麻烦的了,这里配了一个还算可以看的颜色系,别介意~如果你有好的配色方案,请分享下,谢了~^_^

void initColor()//这里需要说明下,虽然写的是bgr,但是这里是当作HSV来初始化的,然后图片绘制完成后直接转下空间即可
{for(int i = 0;i < MAX_COLOR;i++){B[i] = i * 4 % 256;G[i] = 0.7 * 255.0;R[i] = 255.0 * (1.0 - i / 255.0 * i / 255.0 / 1.2);}
}

4、绘制分形:

void drawPic()
{double deltaX = (XMax - XMin) / width;double deltaY = (YMax - YMin) / height;int max_iterations = 256;//最大迭代次数double max_size = 4.0;//这里是2的平方,为什么?建议看看维基百科的介绍~for(int row = 0;row < height;row++){for(int col = 0;col < width;col++){int color = 0;Complex c,z;z.real = 0;//这里是Mandelbrot集,下面被注释掉的是Julia集z.img = 0;c.real  = XMin + col * deltaX;c.img = YMin + row * deltaY;//z.real = XMin + col * deltaX;//z.img = YMin + row * deltaY;//c.real = 0.285;//c.img = 0.01;while((color < max_iterations) && ((z.img * z.img + z.real * z.real) < max_size)){  double tmp = z.real * z.real - z.img * z.img + c.real;z.img = z.img * z.real + z.real * z.img + c.img;z.real = tmp;color++;}if(color >= max_iterations)color = 255;color %= MAX_COLOR;IMG_8UB(fractal,col,row) = B[color];IMG_8UG(fractal,col,row) = G[color];IMG_8UR(fractal,col,row) = R[color];}}cvCvtColor(fractal,fractal,CV_HSV2BGR);//将HSV空间转换为BGR,方便显示cvShowImage("Fractal",fractal);cvSaveImage(name[fileIndex++],fractal);//记录查看过程cvWaitKey(0);
}

5、鼠标事件:

void on_mouse( int event, int x, int y, int flags, void *param  =  NULL)
{if( !fractal)return;if( event == CV_EVENT_LBUTTONDOWN){pt1 = cvPoint(x,y);}else if(  event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) ){pt2 = cvPoint(x,y);int dx = abs(pt2.x - pt1.x);int dy = abs(pt2.y - pt1.y);if(pt1.x > 0 && pt1.y > 0 && pt2.x > 0 && pt2.y > 0&& dx > 5 && dy > 5){cvSaveImage(name[fileIndex++],fcopy);//记录查看过程double DX = XMax - XMin;//接下来转换放大的坐标double DY = YMax - YMin;double offX = DX / width;double offY = DY / height;if(pt1.x < pt2.x){            XMax = offX * pt2.x + XMin;XMin = offX * pt1.x + XMin;}else{            XMax = offX * pt1.x + XMin;XMin = offX * pt2.x + XMin;}if(pt1.y < pt2.y){YMax = offY * pt2.y + YMin;YMin = offY * pt1.y + YMin;}else{YMax = offY * pt1.y + YMin;YMin = offY * pt2.y + YMin;  }pt1 = cvPoint(-1,-1);//注意重新赋值,否则鼠标移动时还会进来,造成重复计算pt2 = cvPoint(-1,-1);printf("XMax:%.15lf XMin:%.15lf\nYMax:%.15lf YMin:%.15lf\n",XMax,XMin,YMax,YMin); drawPic();//重新绘制分形}}else if(event == CV_EVENT_RBUTTONDOWN)//右键取消放大,重新选取放大区域{pt1 = cvPoint(-1,-1);pt2 = cvPoint(-1,-1);}else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )//在选取过程中画矩形{pt2 = cvPoint(x,y);if(pt1.x > 0 && pt1.y > 0 && pt2.x > 0 && pt2.y > 0&& abs(pt2.x - pt1.x) > 5&& abs(pt2.y - pt1.y) > 5){cvCopy(fractal,fcopy);cvRectangle(fcopy,pt1,pt2,cvScalar(255,255,255));cvShowImage( "Fractal", fcopy);}}
}

6、主函数:

int main()
{cvNamedWindow("Fractal",1);cvSetMouseCallback( "Fractal", on_mouse, 0 );//注册鼠标事件fractal = cvCreateImage(cvSize(width,height),8,3);fcopy = cvCreateImage(cvSize(width,height),8,3);initFileName();//初始化initColor();drawPic();cvReleaseImage(&fractal);cvReleaseImage(&fcopy);cvDestroyWindow("Fractal");for(int i = 0;i < 100;i++)free(name[i]);return 0;
}

今天花了一天的时间在这上面,但是,很值得~

让我来看看这些美丽的分形吧~

下面是Julia集:

c = 0.285, 0.01

c = 0.285, 0

c = -0.8, 0.156

c = -0.835, -0.2321

c = -0.70176, -0.3842

c = 0.45, -0.1428

今天的收获还是挺大的,起码,这些美丽无比的画,让我真正体会到了数学之美。

不过还是有点遗憾,毕竟没有把颜色配好,不是非常好看,比起维基百科上的那些图片简直没法比。

还有就是对这两个集合没有深入理解,有时间还要研究下。

STL的complex实在太操蛋了,太慢了,我用complex要用将近一分钟才能出一幅画!!!

据说用多线程能加快计算,看来我得学下了~

数学之美之分形——C++及OpenCV实现Julia集和Mandelbrot集绘制相关推荐

  1. 分形之Julia集和Mandelbrot集及浅谈分形理论的应用

    首先要show一把这俩个集合的图片 [img]http://upload.wikimedia.org/wikipedia/commons/a/a4/Mandelbrot_sequence_new.gi ...

  2. 神奇的分形艺术(四):Julia集和Mandelbrot集

    考虑函数f(z)=z^2-0.75.固定z0的值后,我们可以通过不断地迭代算出一系列的z值:z1=f(z0), z2=f(z1), z3=f(z2), ....比如,当z0 = 1时,我们可以依次迭代 ...

  3. 【数学之美】分形图形动画演示欣赏

    IT派助力深广创业,免费代发招聘信息,了解一下? 科赫曲线 Koch curve: H分形 H-fractal: 谢尔宾斯基三角形Sierpinski triangle: 维切克分形 Vicsek f ...

  4. 【数学之美】分形——发现隐藏的维度

    仔细回想一下,在我们的生活中,无论是蜿蜒曲折的海岸线.绵延的山脊.变幻无常的云团,盘根错节的树根,还是人体的毛细血管,尽管它们的形状是不规则的,但如果用不同倍数的镜头来观察,它们的局部.分支和整体都有 ...

  5. 数学之美--数学大师与漂亮的分形几何学

    <美国数学会会志>今年连续在9月号和10月号上刊发忆述文章,回忆了美籍法国数学大师."分形几何学之父"伯努瓦·曼德尔布罗的奋斗历程,并高度评价他为科学发展作出了巨大贡献 ...

  6. Matlab:数学之美--绘制分形图形

    Matlab:数学之美–绘制分形图形 学习最好的动力是兴趣,所以我们先看看效果: 这一篇与Java学习日记:数学之美-分形图形绘制有共同之处,只是所用的工具不同. clear; %不同的参数有不同的图 ...

  7. 【影分身之术】制作迷人图片小菜一碟——数学与美的极致结合

    如果你看过分形和其接近无限的变焦功能,你一定会整天盯着这些图,因为它们要多有趣就可以多有趣.分形,是以非整数维形式充填空间的形态特征,应用在图片处理中,会产生惊人的美,不仅是视觉上的娱乐,最主要的是它 ...

  8. MATLAB | 一起来感受数学之美叭

    前两天去观摩了MATHWORKS官方举办的Mathematics is beautiful数学之美投票比赛,见到了很多非常惊艳的作品,在这里分享给大家让大家一同感受大神们的创造力,接下来由我来做全程解 ...

  9. 贝叶斯定理——数学之美

    1.贝叶斯定理 1.1 定义:描述在已知一些条件下,某事件的发生概率 贝叶斯定理是关于随机事件A和B的条件概率的一则定理. 1.2 公式理解 P(x∣y)=P(x)P(y∣x)P(y)P(x|y) = ...

最新文章

  1. 在CentOS/Debian/Ubuntu上编译安装最新版 GCC 8 , cmake 3 和ninja
  2. 轻松掌握ISO8583报文协议
  3. Leetcode 167. 两数之和 II - 输入有序数组 (每日一题 20210818)
  4. 1008-----算法笔记----------0-1背包问题(动态规划求解)
  5. 【图像超分辨率】Multi-scale Residual Network for Image Super-Resolution
  6. pycharm安装xlrd失败_Pycharm 下载与安装 详解
  7. JVM调优——Java动态编译过程中的内存溢出问题
  8. SAP License:产品成本估算结果表
  9. 线上 ELK 集群健康值 red 状态问题排查与解决
  10. Java中的深拷贝与浅拷贝
  11. 数学建模算法体系分类
  12. 近日onedrive突然消失问题的解决
  13. 元宵节大家来猜灯谜,祝元宵节快乐!
  14. anchor机制讲解
  15. 滑头杨百万的股经:六分心态三分技巧一分运气
  16. 微软认证70-541,70-542等考试试题(80%以上的题目是一样的)
  17. python写的创世区块
  18. Spring Boot搭建简易spring clound框架 (一)
  19. Profile 是什么意思
  20. 乐鑫Esp32学习之旅 19 重磅开源,如何在微信小程序上ble蓝牙配网esp32,blufi的那些事!

热门文章

  1. 普元软件推动企业应用架构转型互联网
  2. 198. House Robber 的递归与动态规划实现方法(Python)
  3. 伯克利双专业 经济学和计算机专业,美国加州伯克利大学世界排名第几2021
  4. 【HTCVR】VRTK插件案例分析之0011~020
  5. STM32 使用 ITM 输出调试信息
  6. 【线性代数】5-3:克莱姆法则,逆和体积(Cramers Rule,Inverses,and Volumes)
  7. 经典文献阅读之--Cam2BEV
  8. 大数据课程综合实验案例:网站用户行为分析
  9. 有创意的LED电子骰子
  10. 2022年安全员-B证考试模拟100题及在线模拟考试