初识分形

1、分形的含义:

英文单词Fractal,它是由美籍法国数学家曼德勃罗(Benoit Mandelbrot)创造出来的。其含义是不规则的、破碎的、分数的。曼德勃罗是想用此词来描述自然界中传统欧几里得几何学所不能描述的一大类复杂无规的几何对象。

2、分形的几何特征:

自相似性:自相似,便是局部与整体的相似。

自仿射性:自仿射性是自相似性的一种拓展。如果,将自相似性看成是局部到整体在各个方向上的等比例变换的结果的话,那么,自仿射性就是局部到整体在不同方向上的不等比例变换的结果。前者称为自相似变换,后者称为自仿射变换。

精细结构:任意小局部总是包含细致的结构。

3、分形与计算机科学:

分形理论的发展离不开计算机图形学的支持,如果一个分形构造的表达,不用计算机的帮助是很难让人理解的。不仅如此,分形算法与现有计算机图形学的其他算法相结合,还会产生出非常美丽的图形,而且可以构造出复杂纹理和复杂形状,从而产生非常逼真的物质形态和视觉效果。

分形作为一种方法,在图形学领域主要是利用迭代、递归等技术来实现某一具体的分形构造。

分形几何学与计算机图形学相结合,将会产生一门新的学科——分形图形学。它的主要任务是以分形几何学为数学基础,构造非规则的几何图素,从而实现分形体的可视化,以及对自然景物的逼真模拟。

本文地址:http://www.cnblogs.com/archimedes/p/fractal-c.html,转载请注明源地址。

分形图的递归算法

递归算法就不赘述了,凡是搞编程的应该都不陌生,可以参考我早前写过的一些递归程序题目小练一下:《递归练习(C语言)

以Koch曲线的递归算法为例:

代码如下:

  1. #include<stdio.h>
  2. #include<math.h>
  3. #include<conio.h>
  4. #include"graphics.h"
  5. void koch(double x0, double y0, double x1, double y1, int k)
  6. {
  7. double x2, y2, x3, y3, x4, y4;
  8. x2 = 2.0/ * x0 + 1.0/ * x1; /*由上面的运算可以得到其余三点 坐标的计算式*/
  9. y2 = 2.0/ * y0 + 1.0/ * y1;
  10. x3 = 1.0/ * x0 + 2.0/ * x1;
  11. y3 = 1.0/ * y0 + 2.0/ * y1;
  12. x4 = 1.0/ * (x0 + x1) - sqrt(3.0)/ * (y1 - y0);
  13. y4 = 1.0/ * (y0 + y1) + sqrt(3.0)/ * (x1 - x0);
  14. if( k > ) /*如果迭代次数大于1,就继续迭代下去,即执行以下程序*/
  15. {
  16. koch(x0, y0, x2, y2, k - ); /*对以(x0, y0)和(x2, y2)为端点的线段作为
  17. 初始线段进行迭代运算,以下类同*/
  18. koch(x2, y2, x4, y4, k - );
  19. koch(x4, y4, x3, y3, k - );
  20. koch(x3, y3, x1, y1, k - );
  21. } else { /*如果迭代次数等于1,停止迭代,画出迭代生成的图形*/
  22. line(x0, y0, x2, y2); /*用直线联结两点(x0, y0)和(x2, y2)*/
  23. line(x2, y2, x4, y4); /*用直线联结两点(x2, y2)和(x4, y4)*/
  24. line(x4, y4, x3, y3); /*用直线联结两点(x4, y4)和(x3, y3)*/
  25. line(x3, y3, x1, y1); /*用直线联结两点(x3, y3)和(x1, y1)*/
  26. }
  27. }
  28.  
  29. int main()
  30. {
  31. int n, gdriver = DETECT, gmode; /*定义迭代次数n*/
  32. initgraph(&gdriver, &gmode,"C:\\Win-TC\\BGI"); /*图形系统初始化*/
  33. printf("Please input the value of the positive integer n (n<9):");
  34. scanf("%d", &n); /*输入迭代次数n*/
  35. setcolor(GREEN);
  36. koch(, , , , n);
  37. getch();
  38. closegraph(); /*关闭图形系统*/
  39. return ;
  40. }

LS文法

LS文法先定义了绘图规则:

F:以当前方向前进一步,并画线;

f:以当前方向前进一步,不画线;

+:逆时针旋转角;

-:顺时针旋转角;

[:表示暂时保存当前的画图状态;

]:表示提取出保存的画图状态。 “[”和“]”要成对的出现。

Koch曲线的LS文法如下:

w:F(初始字母)

a :60(旋转角度)

P:F → F + F - - F + F(F的替代文法)

根据这一文法生成Koch曲线的步骤(假设迭代两次):

第一步: 得到迭代两次的文法。

第一次迭代结果:

F + F - - F + F

第二次迭代结果:(第一次迭代得到的结果的每一个F用规则P替换)

F + F - - F + F + F + F - - F + F - - F + F - - F + F + F + F - - F + F

第二步:按照迭代得到的文法绘图。

当然,还有实现其他分形图的LS文法,这里就不一一举出了

下面的算法没有用递归,纯C语言实现:

  1. /****************************************************
  2. ** Completed on 2014.11.11 11:11
  3. ** Programming environment:win xp + win-tc 2.0
  4. ** Language: ANSI C
  5. ** copyright(c) codingwu (Email: oskernel@126.com)
  6. *****************************************************/
  7. #include<stdio.h>
  8. #include<stdlib.h>
  9. #include<math.h>
  10. #include<string.h>
  11. #include<ctype.h>
  12. #include<malloc.h>
  13. #include<conio.h>
  14. #include<graphics.h>
  15.  
  16. #define PI 3.1415926
  17. #define stacksize 1024
  18.  
  19. typedef struct _point {
  20. double x;
  21. double y;
  22. double delta;
  23. }point;
  24.  
  25. typedef struct _L_Sys {
  26. char *name;
  27. char *startStr; /* 初始字符串 */
  28. char *replaceF;
  29. char *replaceX; /* 替换X字符串 */
  30. char *replaceY; /* 替换Y字符串 */
  31. char *replaceS; /* 替换S字符串 */
  32. char *replaceG; /* 替换G字符串 */
  33. char *replaceK; /* 替换K字符串 */
  34. char *replaceL; /* 替换L字符串 */
  35. char *replaceH; /* 替换H字符串 */
  36. int StartX; /* 起始点坐标 */
  37. int StartY;
  38. int depth; /* 递归深度 */
  39. int ruleNumber; /* 规则数 */
  40. double angle;
  41. double direct_init;
  42. double length;
  43.  
  44. }L_Sys;
  45.  
  46. L_Sys ls[];
  47.  
  48. void init_L_Sys(L_Sys *LS, char *_name, char *_startStr, char *_replaceF,
  49. char *_replaceX, char *_replaceY, char *_replaceS, char *_replaceG,
  50. char *_replaceK, char *_replaceL, char *_replaceH, int _StartX,
  51. int _StartY, int _depth, int _ruleNumber, double _angle,
  52. double _direct_init, double _length) /* 初始化 */
  53. {
  54. (*LS).name = (char *)malloc(strlen(_name) + );
  55. if((*LS).name == NULL) return;
  56. strcpy((*LS).name, _name);
  57. (*LS).startStr = (char *)malloc(strlen(_startStr) + );
  58. if((*LS).startStr == NULL) return;
  59. strcpy((*LS).startStr, _startStr);
  60. (*LS).replaceF = (char *)malloc(strlen(_replaceF) + );
  61. if((*LS).replaceF == NULL) return;
  62. strcpy((*LS).replaceF, _replaceF);
  63. (*LS).replaceX = (char *)malloc(strlen(_replaceX) + );
  64. if((*LS).replaceX == NULL) return;
  65. strcpy((*LS).replaceX, _replaceX);
  66. (*LS).replaceY = (char *)malloc(strlen(_replaceY) + );
  67. if((*LS).replaceY == NULL) return;
  68. strcpy((*LS).replaceY, _replaceY);
  69. (*LS).replaceS = (char *)malloc(strlen(_replaceS) + );
  70. if((*LS).replaceS == NULL) return;
  71. strcpy((*LS).replaceS, _replaceS);
  72. (*LS).replaceG = (char *)malloc(strlen(_replaceG) + );
  73. if((*LS).replaceG == NULL) return;
  74. strcpy((*LS).replaceG, _replaceG);
  75. (*LS).replaceK = (char *)malloc(strlen(_replaceK) + );
  76. if((*LS).replaceK == NULL) return;
  77. strcpy((*LS).replaceK, _replaceK);
  78. (*LS).replaceL = (char *)malloc(strlen(_replaceL) + );
  79. if((*LS).replaceL == NULL) return;
  80. strcpy((*LS).replaceL, _replaceL);
  81. (*LS).replaceH = (char *)malloc(strlen(_replaceH) + );
  82. if((*LS).replaceH == NULL) return;
  83. strcpy((*LS).replaceH, _replaceH);
  84. (*LS).StartX = _StartX;
  85. (*LS).StartY = _StartY;
  86. (*LS).depth = _depth;
  87. (*LS).ruleNumber = _ruleNumber;
  88. (*LS).angle = _angle;
  89. (*LS).direct_init = _direct_init;
  90. (*LS).length = _length;
  91. }
  92.  
  93. void init(int n)
  94. {
  95. /*init_L_Sys(&ls[i], "hualei", "Start", "F", "X", "Y", "S", "G", "K", "L", "H",
  96. pStartX, pStartY, depth, ruleNumber, angle, direct_init, length); */
  97. switch(n) {
  98. case :
  99. init_L_Sys(&ls[], "xiecao", "G", "F-XF", "", "", "",
  100. "GFX[+++++GFG][-----GFG]", "", "", "", , , , , -, , 3.3);
  101. break;
  102. case :
  103. init_L_Sys(&ls[], "shusan", "X", "FF", "--FXF++FXF++FXF--", "", "",
  104. "", "", "", "", , , , , -, , );
  105. break;
  106. case :
  107. init_L_Sys(&ls[], "hualei", "F", "F[+F[+F][-F]F][-F[+F][-F]F]F[+F][-F]F",
  108. "", "", "", "", "", "", "", , , , , , , );
  109. break;
  110. case :
  111. init_L_Sys(&ls[], "shuzhi", "K", "", "", "", "[+++G][---H]FFS",
  112. "G+G[-FH]F", "FSF", "", "-H[+FG]F",
  113. , , , , -, -, 9.5);
  114. break;
  115. case :
  116. init_L_Sys(&ls[], "shuzhi", "F", "F[+F]F[-F]F", "", "", "",
  117. "", "", "", "",
  118. , , , , -25.7341, , 1.5);
  119. break;
  120. case :
  121. init_L_Sys(&ls[], "korch", "F", "F[+F]F[-F]F", "", "", "",
  122. "", "", "", "",
  123. , , , , -25.7341, , 1.5);
  124. break;
  125. case :
  126. init_L_Sys(&ls[], "pugongying", "Y", "", "X[-FFF][+FFF]FX",
  127. "YFX[+Y][-Y]", "", "", "", "", "",
  128. , , , , , , 0.37);
  129. break;
  130. case :
  131. init_L_Sys(&ls[], "guanmucong", "F", "FF-[-F+F+F]+[+F-F-F]", "", "",
  132. "", "", "", "", "",
  133. , , , , -, , 3.5);
  134. break;
  135.  
  136. case :
  137. init_L_Sys(&ls[], "kaihuadecao", "G", "", "XFX", "", "",
  138. "[+FGF][-FGF]XG", "", "", "",
  139. , , , , -, , );
  140. break;
  141. case :
  142. init_L_Sys(&ls[], "guanmucong2", "F",
  143. "F[+++++++++++++++++++++++++F]-F[-------------------------F]F", "", "",
  144. "", "", "", "", "",
  145. , , , , -1.2, , );
  146. break;
  147. case :
  148. init_L_Sys(&ls[], "yangliu", "F", "FF+[+F-F-F]-[-F+F+F]", "", "",
  149. "", "", "", "", "", , , , , -22.5, , );
  150. break;
  151. case :
  152. init_L_Sys(&ls[], "Juliet", "X", "", "X+YF+", "-FX-Y", "", "", "", "", "",
  153. , , , , , , );
  154. case :
  155. init_L_Sys(&ls[], "zhuanqiang", "X", "", "XFYFX+F+YFXFY-F-XFYF",
  156. "YFXFY-F-XFYFX+F+YFXFY", "", "", "", "", "",
  157. , , , , , , );
  158. break;
  159. case :
  160. init_L_Sys(&ls[], "zhuanqiang_X", "F+F+F+F", "F+F-F-FF+F+F-F", "",
  161. "", "", "", "", "", "",
  162. , , , , , , 3.5);
  163. break;
  164. case :
  165. init_L_Sys(&ls[], "sanjiaoraosanjiao", "X", "FFF", "--FXF++FXF++FXF--",
  166. "", "", "", "", "", "",
  167. , , , , -, , 1.7);
  168. break;
  169. case :
  170. init_L_Sys(&ls[], "yibimigong", "X", "", "-YF+XFX+FY-", "+XF-YFY-FX+",
  171. "", "", "", "", "",
  172. , , , , -, , );
  173. case :
  174. init_L_Sys(&ls[], "shu", "X", "FF", "F[+X]F[-X]+X", "", "", "", "", "", "",
  175. , , , , , , 0.35);
  176. case :
  177. init_L_Sys(&ls[], "duichengdeshu", "X", "FF", "F[+X][-X]FX", "", "",
  178. "", "", "", "",
  179. , , , , , , 0.35);
  180. break;
  181. default:
  182. break;
  183. }
  184. return;
  185.  
  186. }
  187.  
  188. void freeMemory(L_Sys *LS) /* 释放内存 */
  189. {
  190. free((*LS).name);
  191. (*LS).name = NULL;
  192. free((*LS).startStr);
  193. (*LS).startStr = NULL;
  194. free((*LS).replaceF);
  195. (*LS).replaceF = NULL;
  196. free((*LS).replaceX);
  197. (*LS).replaceX = NULL;
  198. free((*LS).replaceY);
  199. (*LS).replaceY = NULL;
  200. free((*LS).replaceS);
  201. (*LS).replaceS = NULL;
  202. free((*LS).replaceG);
  203. (*LS).replaceG = NULL;
  204. free((*LS).replaceK);
  205. (*LS).replaceK = NULL;
  206. free((*LS).replaceL);
  207. (*LS).replaceL = NULL;
  208. free((*LS).replaceH);
  209. (*LS).replaceH = NULL;
  210. }
  211.  
  212. void fileCopy(FILE *dest, FILE *src) /* 复制文件函数 */
  213. {
  214. char ch;
  215. fseek(src, , SEEK_SET);
  216. ch = fgetc(src);
  217. while(ch != EOF) {
  218. fputc(ch, dest);
  219. ch = fgetc(src);
  220. }
  221. }
  222.  
  223. void fractal(int curr_string) /* 核心功能函数 */
  224. {
  225. int i, j, k, size, depth, len;
  226. char a[], ch;
  227. double Delta;
  228. FILE *result, *tmp;
  229. point stack[stacksize];
  230. point *p;
  231. point bef, aft;
  232.  
  233. tmp = fopen("B.txt","w+");
  234. if(tmp == NULL) return;
  235. init(curr_string);
  236. p = stack;
  237. fputs(ls[curr_string].startStr, tmp);
  238. depth = ls[curr_string].depth;
  239. len = ls[curr_string].length;
  240. for(i = ; i < depth; i++) {
  241. result = fopen("A.txt","w+");
  242. if(result == NULL) return;
  243.  
  244. fseek(tmp, , SEEK_SET);
  245. ch = fgetc(tmp);
  246. while(ch != EOF) { /* F X Y S G K L H*/
  247. if(ch == 'F') {
  248. fputs(ls[curr_string].replaceF, result);
  249. } else if (ch == 'X') {
  250. fputs(ls[curr_string].replaceX, result);
  251. } else if (ch == 'Y') {
  252. fputs(ls[curr_string].replaceY, result);
  253. } else if (ch == 'S') {
  254. fputs(ls[curr_string].replaceS, result);
  255. } else if (ch == 'G') {
  256. fputs(ls[curr_string].replaceG, result);
  257. } else if (ch == 'K') {
  258. fputs(ls[curr_string].replaceK, result);
  259. } else if (ch == 'L') {
  260. fputs(ls[curr_string].replaceL, result);
  261. } else if (ch == 'H') {
  262. fputs(ls[curr_string].replaceH, result);
  263. } else {
  264. fputc(ch, result);
  265. }
  266. ch = fgetc(tmp);
  267. }
  268. fseek(tmp, , SEEK_SET);
  269. fileCopy(tmp, result);
  270. fclose(result);
  271. }
  272. bef.x = ls[curr_string].StartX;
  273. bef.y = ls[curr_string].StartY;
  274.  
  275. bef.delta = PI * (ls[curr_string].angle)/;
  276. Delta = PI * (ls[curr_string].angle)/; /* 转换为弧度制 */
  277.  
  278. result = fopen("A.txt","r");
  279. fseek(result, , SEEK_SET);
  280. ch = fgetc(result);
  281. while(ch != EOF) {
  282.  
  283. switch(ch) {
  284. case 'F':
  285. case 'X':
  286. case 'Y':
  287. case 'S':
  288. case 'G':
  289. case 'K':
  290. case 'L':
  291. case 'H':
  292. aft.x = bef.x + len * cos(bef.delta);
  293. aft.y = bef.y - len * sin(bef.delta);
  294. aft.delta = bef.delta;
  295. line(bef.x, - bef.y, aft.x, - aft.y);
  296.  
  297. bef.x = aft.x;
  298. bef.y = aft.y;
  299. bef.delta = aft.delta;
  300. break;
  301. case '+':
  302. bef.delta += Delta;
  303. break;
  304. case '-':
  305. bef.delta -= Delta;
  306. break;
  307. case '[':
  308. *(p++) = bef;
  309. break;
  310. case ']':
  311. bef = *(--p);
  312. break;
  313. default:
  314. break;
  315. }
  316. ch = fgetc(result);
  317. }
  318. fclose(tmp);
  319. fclose(result);
  320. freeMemory(&ls[curr_string]);
  321. }
  322.  
  323. int main(void)
  324. {
  325. char ch;
  326. int n, gdriver = DETECT, gmode;
  327. wu:
  328. printf("xiecao:0 shusan:1 hualei:2 shuzhi1:3 shuzhi2:4\n"); /* 说明 */
  329. printf("korch:5 pugongying:6 guanmucong:7 kaihuadecao:8 guanmucong2:9\n");
  330. printf("yangliu:10 Juliet:11 zhuanqiang:12 zhuanqiang_X:13 sanjiaoraosanjiao:14\n");
  331. printf("yibimigong:15 shu:16 duichengdeshu:17\n");
  332. printf("guanmucong2:9\n");
  333. printf("continue?(Y/N)\n");
  334. ch = getchar();
  335. if(ch == 'n' || ch == 'N')
  336. return ;
  337. else {
  338. printf("please input a non-negative number to choose which image you what to see(0 <= n <= 17 ): ");
  339. scanf("%d", &n);
  340.  
  341. initgraph(&gdriver, &gmode,"C:\\Win-TC\\BGI"); /*图形系统初始化*/
  342. setcolor(GREEN); /* 设置画笔的颜色 */
  343. fractal(n);
  344. getch();
  345. closegraph(); /*关闭图形系统*/
  346. getchar();
  347. goto wu;
  348. }
  349. return ;
  350. }

分形几何算法和实现(C语言)的更多相关文章

  1. 关于中值滤波算法,以及C语言实现(转)

    源:关于中值滤波算法,以及C语言实现 1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制 ...

  2. 基于BP神经网络的简单字符识别算法自小结(C语言版)

    本文均属自己阅读源代码的点滴总结.转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email:gzzaigcn2009@163.com 写在前面的闲话: 自我感觉自己应该不是一个非常 ...

  3. FFT算法理解与c语言的实现

    完整内容迁移至 http://www.face2ai.com/DIP-2-3-FFT算法理解与c语言的实现/ http://www.tony4ai.com/DIP-2-3-FFT算法理解与c语言的实现 ...

  4. 【操作系统】银行家算法实现(C语言)

    [操作系统]银行家算法实现(C语言) 注意:本人编码水平很菜.算是自己的一个总结.可能会有我还没有发现的bug.如果有人发现后可以指出,不胜感激. 1.银行家算法: 我们可以把操作系统看作是银行家,操 ...

  5. 【操作系统】页面置换算法(最佳置换算法)(C语言实现)

    [操作系统]页面置换算法(最佳置换算法)(C语言实现) (编码水平较菜,写博客也只是为了个人知识的总结和督促自己学习,如果有错误,希望可以指出) 1.页面置换算法: 在地址映射过程中,若在页面中发现所 ...

  6. Floyd算法(一)之 C语言详解

    本章介绍弗洛伊德算法.和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3 ...

  7. Dijkstra算法(一)之 C语言详解

    本章介绍迪杰斯特拉算法.和以往一样,本文会先对迪杰斯特拉算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法 ...

  8. Prim算法(一)之 C语言详解

    本章介绍普里姆算法.和以往一样,本文会先对普里姆算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里 ...

  9. Kruskal算法(一)之 C语言详解

    本章介绍克鲁斯卡尔算法.和以往一样,本文会先对克鲁斯卡尔算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 最小生成树 2. 克鲁斯卡尔算法介绍 3 ...

随机推荐

  1. 【原创】MYSQL++源码剖析——前言与目录

    终于完成了! 从第一次想写到现在真的写好大概花了我3个月时间.原来一直读人家的系列文章,总感慨作者的用心良苦和无私奉献,自己在心里总是会觉得有那么些冲动也来写一个. 最开始的麻烦是犹豫该选哪个主题.其 ...

  2. Asphyre 更名pxl 终于全面支持跨平台了.Delphi饭们 激动了吧.

    Asphyre We are happy to announce the official release of our latest framework Pascal eXtended Librar ...

  3. Webkit CSS properties

    Webkit CSS properties -webkit-animation -webkit-animation-delay -webkit-animation-direction -webkit- ...

  4. 2次成功投诉EMS和中国移动的经验

    上个月要找房子,搬家很多事情,真实头疼...搬家还把腰闪了....现在还有点痛.然后中间碰到 移动宽带 移机的事情,搞得我非常火.然后想起去年投诉EMS的事情,在事情处理完成后,我果断总结了下来,让大 ...

  5. LoopBack – 开源的,可扩展的 Node.js 框架

    LoopBack 是建立在 Express 基础上的开源 Node.js 框架,专门为 Mobile,Web 和其他设备做了优化.LoopBack 能够连接到多个数据源,使用 Node.js 编写业务 ...

  6. Mysql 修改密码及重置密码方法

    修改密码: //选择数据库 use mysql; //修改密码 update user set password=password('新密码') where user='root'; //立即生效 f ...

  7. 在Kibana上格式化字段,更好的在dashboard上展示

    一.为什么要格式化? 接着之前的文章-利用 ELK系统分析Nginx日志并对数据进行可视化展示.下面是http访问的日志,里面有一个字段,bytes 传输的字节,如下图: 绿色框框内选中的就是本次请求 ...

  8. jquery easyui dialog Bug解决方案

    最近一直都在用easyui前端框架来开发设计UI,但在使用Dialog时,发现如果页面内容比较多,就会出现问题,首先看一下我的原代码: <input type="button" ...

  9. 代码规范之争——[个人Week2作业]

    这四个问题均是出自 http://goodmath.scientopia.org/2011/07/14/stuff-everyone-should-do-part-2-coding-standards ...

  10. Entity FrameWork 延迟加载的本质(一)

    1.集合的标准查询运算符方法,是来自于System.Linq.Enumerable里给IEnumerable接口添加的扩展方法 2.EF上下文里的DBSet<T>里的标准查询运算符方法,来 ...