这学期的线下C语言课程,大一学生学完递归后,为了加深对递归的理解,布置了一次分形图片生成实验的PBL。这次,介绍同学们实现的曼德勃罗集。以下提供了分步骤的实现思路、代码,大家可以参考。

同学们调研的目标效果

曼德勃罗特集被称为“上帝的指纹”。这个点集出自公式:Zn+1=Zn2+C,取Z0=0,然后在复平面上选取一点C,数列{Zn}就能递推下去,如果选取的C能不使{Zn}发散,我们就把它加入曼德勃罗特集。

只要你计算的点足够多,不管你把图案放大多少倍,都能显示出更加复杂的局部,这些局部既与整体不同,又与整体相似,从它出发可以产生无穷无尽美丽图案。

最终交互绘制效果

依次实现步骤

第一步

•实现计算的核心:{Z}数列的计算

•为了方便复数的计算我们还为复数定义了一个结构体

•{Z}数列其递推式Zn+1=Zn2+C很明显可以用递归来实现。

•递归的伪代码如下:

第二步

•根据计算结果得到图案,我们没有办法做到无限次迭代,解决方法有二:

1.我们用“迭代很多次”看成“迭代无限次”,越是边界迭代越多。

2.根据数学上结论,曼德勃罗集图像会被半径为2的圆围住,所以迭代出圆后直接返回。

•然后通过查询easyx可知绘制某个像素点的函数是putpixel

•将背景设为白色,点集上的点设为黑色能得到初步图形(好丑啊啊啊啊)

第三步

•美化一下。

•形状上,为了能更精细化我们增加以下Z数列的迭代次数(10次---->500次)

•颜色上,对于不同的点,想要迭代出去的话,迭代次数可能不同。根据迭代次数来划分颜色,选取的是蓝色,迭代次数越多蓝色越深。

第四步

•实现交互放大效果

•首先实现一个函数calc(double X,double Y,double L),功能是画“左上角坐标为(X,Y),长度为L的矩形内的曼德勃罗集”。其中每个像素点和坐标轴的换算为 L/画布长度。

•具体要放大哪一部分呢?我们可以获取用鼠标点击的坐标,来确定放大的范围。

最终代码

#include <graphics.h>
#include <conio.h>
#include <stdio.h>
COLORREF ys[810][810];
MOUSEMSG m1,m2;
int lastx=0,lasty=0,now,maxnow;
double goneX[233],goneY[233],goneL[233];
struct fushu
{double a,b;
};int pan(double x,double y)
{int i;double a,b;fushu Z;Z.a=Z.b=0;for(i=1;i<=500;++i){a=Z.a;b=Z.b;Z.a=a*a-b*b;Z.b=2*a*b;Z.a+=x;Z.b+=y;if(Z.a*Z.a+Z.b*Z.b>4)return i;}return 0;
}
void suan(double x,double y,double len)
{int i,j,k;double dw=len/800;for(i=1;i<=800;++i){for(j=1;j<=800;++j){k=pan(x+i*dw,y-j*dw);if(k>=20)ys[i][j]=RGB(k*2,k*2,k*5);else ys[i][j]=RGB(0,0,k*10);}}
}
void show1()//无矩形
{BeginBatchDraw();int i,j;for(i=1;i<=800;++i){for(j=1;j<=800;++j){putpixel(i,j,ys[i][j]);}}FlushBatchDraw();
}
void show2()//有矩形
{BeginBatchDraw();int i;for(i=m1.x;i<=lastx;++i)putpixel(i,m1.y,ys[i][m1.y]);for(i=m1.x;i<=lastx;++i)putpixel(i,lasty,ys[i][lasty]);for(i=m1.y;i<=lasty;++i)putpixel(m1.x,i,ys[m1.x][i]);for(i=m1.y;i<=lasty;++i)putpixel(lastx,i,ys[lastx][i]);rectangle(m1.x,m1.y,m2.x,m2.y);lastx=m2.x,lasty=m2.y;FlushBatchDraw();
}
int main()
{initgraph(800,800);setbkcolor(RGB(0,0,0));setlinestyle(PS_SOLID,1);double X=-2,Y=2,L=4;maxnow=now=1;goneX[now]=X;goneY[now]=Y;goneL[now]=L;while(1){WYJ:cleardevice();suan(X,Y,L);show1();while(1){while(1){if(kbhit()){char c=_getch();if((c=='z'||c=='Z')&&now>1){now--;X=goneX[now];Y=goneY[now];L=goneL[now];goto WYJ;}if((c=='y'||c=='Y')&&now<maxnow){now++;X=goneX[now];Y=goneY[now];L=goneL[now];goto WYJ;}}if(MouseHit()){m1=GetMouseMsg();break;}}if(m1.uMsg==WM_LBUTTONDOWN)break;}while(1){while(1){if(MouseHit()){m2=GetMouseMsg();break;}}show2();if(m2.uMsg==WM_LBUTTONUP)break;}X+=m1.x/800.0*L;Y-=m1.y/800.0*L;L=min(m2.x-m1.x,m2.y-m1.y)/800.0*L;++now;maxnow=now;goneX[now]=X;goneY[now]=Y;goneL[now]=L;}_getch();closegraph();return 0;
}

总结体会

1,复杂的问题往往可以分解为几个简单重复的部分,使问题化繁为简,迎刃而解。

2,在这次代码中,我们用到了一些新的函数,如画点函数。让我们熟悉了对EasyX的使用。

3,在活动中,我们通过分工合作,最后实现这一效果,深刻认识到了合作的重要性。

4,代码的优化很有必要,我们在第一次实现画鼠标的方框,画放大图像,按z撤销按y恢复这几个功能时都出现了卡顿,后来通过优化算法,找出bug,省去多余步骤等方法消除了卡顿。

5.这次代码中细节较多,使用了很多函数,提高了正确性,并简化了代码(106行)

更多趣味学C语言教程,可以参考之前写的图书:

如果对趣味学Python感兴趣,也可以参考:

C语言递归分形实验-曼德勃罗集相关推荐

  1. python绘制分形图基础_Python 绘制分形图(曼德勃罗集、分形树叶、科赫曲线、分形龙、谢尔宾斯基三角等)附代码...

    1. 曼德勃罗集 import numpy as np import pylab as pl import time from matplotlib import cm def iter_point( ...

  2. 浅析曼德勃罗集及C++实现图形绘制

    在算法大作业中,认识到了曼德勃罗集(Mandelbrot Set)这一名词,经过网上资料的查阅,才对其思想和独特魅力略知皮毛.由于该集合的定义与分形有关,需要先介绍一下分形的概念. 什么是分形(Fra ...

  3. 基于MATLAB和python输出曼德勃罗集

    上帝的指纹--曼德勃罗集 曼德勃罗集可称是人类有史以来做出的最奇异.最瑰丽的几何图形,被人称为"上帝的指纹"."魔鬼的聚合物". 这个点集均出自公式:Zn+1= ...

  4. 【知识搬运】曼德勃罗集—“上帝指纹”

    人类对于宇宙总是有着各种各样的迷思,古往今来,无数的智者在对着深邃的夜空沉思,希望能从中找到答案.他们从追问人类是如何诞生的,到追问宇宙如何诞生的,不断地探索着未知. 而在这个过程中,许多智者也曾&q ...

  5. 如何用python画人像_如何用Python画曼德勃罗集

    先上图好看的曼德勃罗集 错了错了是这个特别好看的曼德勃罗集 当然你需要下载Python(https://www.python.org) 和Visual Studio 2019(https://visu ...

  6. 基于Python画曼德勃罗集

    最近有点迷分型几何,看到"上帝指纹"曼德勃罗集,想用Python实现一下. 源码很简单20行不到. import matplotlib.pyplot as plt import n ...

  7. C语言递归分形实验-毕达哥拉斯树

    这学期的线下C语言课程,大一学生学完递归后,为了加深对递归的理解,布置了一次分形图片生成实验的PBL.这次,介绍同学们实现的毕达哥拉斯树.以下提供了分步骤的实现思路.代码,大家可以参考. 首先是同学们 ...

  8. unity DOTS的学习总结之Job System应用——绘制曼德勃罗集合

    接上回:DOTS的学习总结之Job System的介绍,这次就利用之前了解知识来做点效果. 上回在这:unity DOTS的学习总结之Job System 说到并行处理,那最适合拿来做实验的就是一些分 ...

  9. matlab分形曼德勃罗,曼德勃罗集合分形图案

    三.曼德勃罗集合(Mandelbrot Set) 曼德勃罗集合(Mandelbrot Set)或曼德勃罗复数集合,是一种在复平面上组成分形的点的集合,因由曼德勃罗提出而得名.曼德博集合可以使复二次多项 ...

最新文章

  1. 使用Python的随机数模块 random 实现猜数字游戏
  2. ftp、sftp、vsftp、ssh、vsftpd、sshd
  3. android studio连接真机问题
  4. 无边框处理_PPT别再直接插图片,简单处理一下,瞬间提升你的PPT颜值
  5. CSRF***与防御
  6. 用Java编写约分最简公式,2013年Java方向C组第五题
  7. 解决Linux 忘记root 密码的办法
  8. #前端# 解决前端页面滑动不顺畅的问题
  9. 绑定方法与非绑定方法
  10. 说说Javascript
  11. Oracle删除用户和表空间
  12. 44. Element insertBefore() 方法
  13. 历届二级c语言pdf,国家计算机二级C语言历年真题与答案.pdf
  14. WIN10安装SQL SERVER 2005 服务无法启动
  15. 使用Battery Historian采集android耗电数据
  16. matlab实现简单图形的识别
  17. DDD(领域驱动设计)系列主题:基础概念对象介绍(实体,值对象,仓储等)
  18. 20年,中国互联网主流产品的演变和逻辑
  19. 最强的手机文件管理器!
  20. 【外卖点餐平台项目遇到的问题】

热门文章

  1. ~~试除法求所有约数(附模板题)
  2. 【抄】更改eclipse配置
  3. OneNET物联网云平台HTTP数据流上传与下发,使用Fiddler调试开关应用,stm32 esp8266物联网家居远程开关
  4. invoke-rc.d: initscript systemd-logind, action start failed
  5. 小技巧 ----- Java中指定保留几位小数
  6. 集合 (一) ----- 集合的基本概念与Collection集合详解
  7. 【分享】老鸟程序员才知道的技巧
  8. startService和onBinderService混合开发音乐播放器
  9. 分享两个网址,一个是使用mssql自带的跟踪工具和分析工具
  10. BZOJ 3401: [Usaco2009 Mar]Look Up 仰望( 单调栈 )