分形几何算法和实现(C语言)
初识分形
1、分形的含义:
英文单词Fractal,它是由美籍法国数学家曼德勃罗(Benoit Mandelbrot)创造出来的。其含义是不规则的、破碎的、分数的。曼德勃罗是想用此词来描述自然界中传统欧几里得几何学所不能描述的一大类复杂无规的几何对象。
2、分形的几何特征:
自相似性:自相似,便是局部与整体的相似。
自仿射性:自仿射性是自相似性的一种拓展。如果,将自相似性看成是局部到整体在各个方向上的等比例变换的结果的话,那么,自仿射性就是局部到整体在不同方向上的不等比例变换的结果。前者称为自相似变换,后者称为自仿射变换。
精细结构:任意小局部总是包含细致的结构。
3、分形与计算机科学:
分形理论的发展离不开计算机图形学的支持,如果一个分形构造的表达,不用计算机的帮助是很难让人理解的。不仅如此,分形算法与现有计算机图形学的其他算法相结合,还会产生出非常美丽的图形,而且可以构造出复杂纹理和复杂形状,从而产生非常逼真的物质形态和视觉效果。
分形作为一种方法,在图形学领域主要是利用迭代、递归等技术来实现某一具体的分形构造。
分形几何学与计算机图形学相结合,将会产生一门新的学科——分形图形学。它的主要任务是以分形几何学为数学基础,构造非规则的几何图素,从而实现分形体的可视化,以及对自然景物的逼真模拟。
本文地址:http://www.cnblogs.com/archimedes/p/fractal-c.html,转载请注明源地址。
分形图的递归算法
递归算法就不赘述了,凡是搞编程的应该都不陌生,可以参考我早前写过的一些递归程序题目小练一下:《递归练习(C语言)》
以Koch曲线的递归算法为例:
代码如下:
#include<stdio.h>
#include<math.h>
#include<conio.h>
#include"graphics.h"
void koch(double x0, double y0, double x1, double y1, int k)
{
double x2, y2, x3, y3, x4, y4;
x2 = 2.0/ * x0 + 1.0/ * x1; /*由上面的运算可以得到其余三点 坐标的计算式*/
y2 = 2.0/ * y0 + 1.0/ * y1;
x3 = 1.0/ * x0 + 2.0/ * x1;
y3 = 1.0/ * y0 + 2.0/ * y1;
x4 = 1.0/ * (x0 + x1) - sqrt(3.0)/ * (y1 - y0);
y4 = 1.0/ * (y0 + y1) + sqrt(3.0)/ * (x1 - x0);
if( k > ) /*如果迭代次数大于1,就继续迭代下去,即执行以下程序*/
{
koch(x0, y0, x2, y2, k - ); /*对以(x0, y0)和(x2, y2)为端点的线段作为
初始线段进行迭代运算,以下类同*/
koch(x2, y2, x4, y4, k - );
koch(x4, y4, x3, y3, k - );
koch(x3, y3, x1, y1, k - );
} else { /*如果迭代次数等于1,停止迭代,画出迭代生成的图形*/
line(x0, y0, x2, y2); /*用直线联结两点(x0, y0)和(x2, y2)*/
line(x2, y2, x4, y4); /*用直线联结两点(x2, y2)和(x4, y4)*/
line(x4, y4, x3, y3); /*用直线联结两点(x4, y4)和(x3, y3)*/
line(x3, y3, x1, y1); /*用直线联结两点(x3, y3)和(x1, y1)*/
}
} int main()
{
int n, gdriver = DETECT, gmode; /*定义迭代次数n*/
initgraph(&gdriver, &gmode,"C:\\Win-TC\\BGI"); /*图形系统初始化*/
printf("Please input the value of the positive integer n (n<9):");
scanf("%d", &n); /*输入迭代次数n*/
setcolor(GREEN);
koch(, , , , n);
getch();
closegraph(); /*关闭图形系统*/
return ;
}
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语言实现:
/****************************************************
** Completed on 2014.11.11 11:11
** Programming environment:win xp + win-tc 2.0
** Language: ANSI C
** copyright(c) codingwu (Email: oskernel@126.com)
*****************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<ctype.h>
#include<malloc.h>
#include<conio.h>
#include<graphics.h> #define PI 3.1415926
#define stacksize 1024 typedef struct _point {
double x;
double y;
double delta;
}point; typedef struct _L_Sys {
char *name;
char *startStr; /* 初始字符串 */
char *replaceF;
char *replaceX; /* 替换X字符串 */
char *replaceY; /* 替换Y字符串 */
char *replaceS; /* 替换S字符串 */
char *replaceG; /* 替换G字符串 */
char *replaceK; /* 替换K字符串 */
char *replaceL; /* 替换L字符串 */
char *replaceH; /* 替换H字符串 */
int StartX; /* 起始点坐标 */
int StartY;
int depth; /* 递归深度 */
int ruleNumber; /* 规则数 */
double angle;
double direct_init;
double length; }L_Sys; L_Sys ls[]; void init_L_Sys(L_Sys *LS, char *_name, char *_startStr, char *_replaceF,
char *_replaceX, char *_replaceY, char *_replaceS, char *_replaceG,
char *_replaceK, char *_replaceL, char *_replaceH, int _StartX,
int _StartY, int _depth, int _ruleNumber, double _angle,
double _direct_init, double _length) /* 初始化 */
{
(*LS).name = (char *)malloc(strlen(_name) + );
if((*LS).name == NULL) return;
strcpy((*LS).name, _name);
(*LS).startStr = (char *)malloc(strlen(_startStr) + );
if((*LS).startStr == NULL) return;
strcpy((*LS).startStr, _startStr);
(*LS).replaceF = (char *)malloc(strlen(_replaceF) + );
if((*LS).replaceF == NULL) return;
strcpy((*LS).replaceF, _replaceF);
(*LS).replaceX = (char *)malloc(strlen(_replaceX) + );
if((*LS).replaceX == NULL) return;
strcpy((*LS).replaceX, _replaceX);
(*LS).replaceY = (char *)malloc(strlen(_replaceY) + );
if((*LS).replaceY == NULL) return;
strcpy((*LS).replaceY, _replaceY);
(*LS).replaceS = (char *)malloc(strlen(_replaceS) + );
if((*LS).replaceS == NULL) return;
strcpy((*LS).replaceS, _replaceS);
(*LS).replaceG = (char *)malloc(strlen(_replaceG) + );
if((*LS).replaceG == NULL) return;
strcpy((*LS).replaceG, _replaceG);
(*LS).replaceK = (char *)malloc(strlen(_replaceK) + );
if((*LS).replaceK == NULL) return;
strcpy((*LS).replaceK, _replaceK);
(*LS).replaceL = (char *)malloc(strlen(_replaceL) + );
if((*LS).replaceL == NULL) return;
strcpy((*LS).replaceL, _replaceL);
(*LS).replaceH = (char *)malloc(strlen(_replaceH) + );
if((*LS).replaceH == NULL) return;
strcpy((*LS).replaceH, _replaceH);
(*LS).StartX = _StartX;
(*LS).StartY = _StartY;
(*LS).depth = _depth;
(*LS).ruleNumber = _ruleNumber;
(*LS).angle = _angle;
(*LS).direct_init = _direct_init;
(*LS).length = _length;
} void init(int n)
{
/*init_L_Sys(&ls[i], "hualei", "Start", "F", "X", "Y", "S", "G", "K", "L", "H",
pStartX, pStartY, depth, ruleNumber, angle, direct_init, length); */
switch(n) {
case :
init_L_Sys(&ls[], "xiecao", "G", "F-XF", "", "", "",
"GFX[+++++GFG][-----GFG]", "", "", "", , , , , -, , 3.3);
break;
case :
init_L_Sys(&ls[], "shusan", "X", "FF", "--FXF++FXF++FXF--", "", "",
"", "", "", "", , , , , -, , );
break;
case :
init_L_Sys(&ls[], "hualei", "F", "F[+F[+F][-F]F][-F[+F][-F]F]F[+F][-F]F",
"", "", "", "", "", "", "", , , , , , , );
break;
case :
init_L_Sys(&ls[], "shuzhi", "K", "", "", "", "[+++G][---H]FFS",
"G+G[-FH]F", "FSF", "", "-H[+FG]F",
, , , , -, -, 9.5);
break;
case :
init_L_Sys(&ls[], "shuzhi", "F", "F[+F]F[-F]F", "", "", "",
"", "", "", "",
, , , , -25.7341, , 1.5);
break;
case :
init_L_Sys(&ls[], "korch", "F", "F[+F]F[-F]F", "", "", "",
"", "", "", "",
, , , , -25.7341, , 1.5);
break;
case :
init_L_Sys(&ls[], "pugongying", "Y", "", "X[-FFF][+FFF]FX",
"YFX[+Y][-Y]", "", "", "", "", "",
, , , , , , 0.37);
break;
case :
init_L_Sys(&ls[], "guanmucong", "F", "FF-[-F+F+F]+[+F-F-F]", "", "",
"", "", "", "", "",
, , , , -, , 3.5);
break; case :
init_L_Sys(&ls[], "kaihuadecao", "G", "", "XFX", "", "",
"[+FGF][-FGF]XG", "", "", "",
, , , , -, , );
break;
case :
init_L_Sys(&ls[], "guanmucong2", "F",
"F[+++++++++++++++++++++++++F]-F[-------------------------F]F", "", "",
"", "", "", "", "",
, , , , -1.2, , );
break;
case :
init_L_Sys(&ls[], "yangliu", "F", "FF+[+F-F-F]-[-F+F+F]", "", "",
"", "", "", "", "", , , , , -22.5, , );
break;
case :
init_L_Sys(&ls[], "Juliet", "X", "", "X+YF+", "-FX-Y", "", "", "", "", "",
, , , , , , );
case :
init_L_Sys(&ls[], "zhuanqiang", "X", "", "XFYFX+F+YFXFY-F-XFYF",
"YFXFY-F-XFYFX+F+YFXFY", "", "", "", "", "",
, , , , , , );
break;
case :
init_L_Sys(&ls[], "zhuanqiang_X", "F+F+F+F", "F+F-F-FF+F+F-F", "",
"", "", "", "", "", "",
, , , , , , 3.5);
break;
case :
init_L_Sys(&ls[], "sanjiaoraosanjiao", "X", "FFF", "--FXF++FXF++FXF--",
"", "", "", "", "", "",
, , , , -, , 1.7);
break;
case :
init_L_Sys(&ls[], "yibimigong", "X", "", "-YF+XFX+FY-", "+XF-YFY-FX+",
"", "", "", "", "",
, , , , -, , );
case :
init_L_Sys(&ls[], "shu", "X", "FF", "F[+X]F[-X]+X", "", "", "", "", "", "",
, , , , , , 0.35);
case :
init_L_Sys(&ls[], "duichengdeshu", "X", "FF", "F[+X][-X]FX", "", "",
"", "", "", "",
, , , , , , 0.35);
break;
default:
break;
}
return; } void freeMemory(L_Sys *LS) /* 释放内存 */
{
free((*LS).name);
(*LS).name = NULL;
free((*LS).startStr);
(*LS).startStr = NULL;
free((*LS).replaceF);
(*LS).replaceF = NULL;
free((*LS).replaceX);
(*LS).replaceX = NULL;
free((*LS).replaceY);
(*LS).replaceY = NULL;
free((*LS).replaceS);
(*LS).replaceS = NULL;
free((*LS).replaceG);
(*LS).replaceG = NULL;
free((*LS).replaceK);
(*LS).replaceK = NULL;
free((*LS).replaceL);
(*LS).replaceL = NULL;
free((*LS).replaceH);
(*LS).replaceH = NULL;
} void fileCopy(FILE *dest, FILE *src) /* 复制文件函数 */
{
char ch;
fseek(src, , SEEK_SET);
ch = fgetc(src);
while(ch != EOF) {
fputc(ch, dest);
ch = fgetc(src);
}
} void fractal(int curr_string) /* 核心功能函数 */
{
int i, j, k, size, depth, len;
char a[], ch;
double Delta;
FILE *result, *tmp;
point stack[stacksize];
point *p;
point bef, aft; tmp = fopen("B.txt","w+");
if(tmp == NULL) return;
init(curr_string);
p = stack;
fputs(ls[curr_string].startStr, tmp);
depth = ls[curr_string].depth;
len = ls[curr_string].length;
for(i = ; i < depth; i++) {
result = fopen("A.txt","w+");
if(result == NULL) return; fseek(tmp, , SEEK_SET);
ch = fgetc(tmp);
while(ch != EOF) { /* F X Y S G K L H*/
if(ch == 'F') {
fputs(ls[curr_string].replaceF, result);
} else if (ch == 'X') {
fputs(ls[curr_string].replaceX, result);
} else if (ch == 'Y') {
fputs(ls[curr_string].replaceY, result);
} else if (ch == 'S') {
fputs(ls[curr_string].replaceS, result);
} else if (ch == 'G') {
fputs(ls[curr_string].replaceG, result);
} else if (ch == 'K') {
fputs(ls[curr_string].replaceK, result);
} else if (ch == 'L') {
fputs(ls[curr_string].replaceL, result);
} else if (ch == 'H') {
fputs(ls[curr_string].replaceH, result);
} else {
fputc(ch, result);
}
ch = fgetc(tmp);
}
fseek(tmp, , SEEK_SET);
fileCopy(tmp, result);
fclose(result);
}
bef.x = ls[curr_string].StartX;
bef.y = ls[curr_string].StartY; bef.delta = PI * (ls[curr_string].angle)/;
Delta = PI * (ls[curr_string].angle)/; /* 转换为弧度制 */ result = fopen("A.txt","r");
fseek(result, , SEEK_SET);
ch = fgetc(result);
while(ch != EOF) { switch(ch) {
case 'F':
case 'X':
case 'Y':
case 'S':
case 'G':
case 'K':
case 'L':
case 'H':
aft.x = bef.x + len * cos(bef.delta);
aft.y = bef.y - len * sin(bef.delta);
aft.delta = bef.delta;
line(bef.x, - bef.y, aft.x, - aft.y); bef.x = aft.x;
bef.y = aft.y;
bef.delta = aft.delta;
break;
case '+':
bef.delta += Delta;
break;
case '-':
bef.delta -= Delta;
break;
case '[':
*(p++) = bef;
break;
case ']':
bef = *(--p);
break;
default:
break;
}
ch = fgetc(result);
}
fclose(tmp);
fclose(result);
freeMemory(&ls[curr_string]);
} int main(void)
{
char ch;
int n, gdriver = DETECT, gmode;
wu:
printf("xiecao:0 shusan:1 hualei:2 shuzhi1:3 shuzhi2:4\n"); /* 说明 */
printf("korch:5 pugongying:6 guanmucong:7 kaihuadecao:8 guanmucong2:9\n");
printf("yangliu:10 Juliet:11 zhuanqiang:12 zhuanqiang_X:13 sanjiaoraosanjiao:14\n");
printf("yibimigong:15 shu:16 duichengdeshu:17\n");
printf("guanmucong2:9\n");
printf("continue?(Y/N)\n");
ch = getchar();
if(ch == 'n' || ch == 'N')
return ;
else {
printf("please input a non-negative number to choose which image you what to see(0 <= n <= 17 ): ");
scanf("%d", &n); initgraph(&gdriver, &gmode,"C:\\Win-TC\\BGI"); /*图形系统初始化*/
setcolor(GREEN); /* 设置画笔的颜色 */
fractal(n);
getch();
closegraph(); /*关闭图形系统*/
getchar();
goto wu;
}
return ;
}
分形几何算法和实现(C语言)的更多相关文章
- 关于中值滤波算法,以及C语言实现(转)
源:关于中值滤波算法,以及C语言实现 1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制 ...
- 基于BP神经网络的简单字符识别算法自小结(C语言版)
本文均属自己阅读源代码的点滴总结.转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email:gzzaigcn2009@163.com 写在前面的闲话: 自我感觉自己应该不是一个非常 ...
- FFT算法理解与c语言的实现
完整内容迁移至 http://www.face2ai.com/DIP-2-3-FFT算法理解与c语言的实现/ http://www.tony4ai.com/DIP-2-3-FFT算法理解与c语言的实现 ...
- 【操作系统】银行家算法实现(C语言)
[操作系统]银行家算法实现(C语言) 注意:本人编码水平很菜.算是自己的一个总结.可能会有我还没有发现的bug.如果有人发现后可以指出,不胜感激. 1.银行家算法: 我们可以把操作系统看作是银行家,操 ...
- 【操作系统】页面置换算法(最佳置换算法)(C语言实现)
[操作系统]页面置换算法(最佳置换算法)(C语言实现) (编码水平较菜,写博客也只是为了个人知识的总结和督促自己学习,如果有错误,希望可以指出) 1.页面置换算法: 在地址映射过程中,若在页面中发现所 ...
- Floyd算法(一)之 C语言详解
本章介绍弗洛伊德算法.和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3 ...
- Dijkstra算法(一)之 C语言详解
本章介绍迪杰斯特拉算法.和以往一样,本文会先对迪杰斯特拉算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法 ...
- Prim算法(一)之 C语言详解
本章介绍普里姆算法.和以往一样,本文会先对普里姆算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里 ...
- Kruskal算法(一)之 C语言详解
本章介绍克鲁斯卡尔算法.和以往一样,本文会先对克鲁斯卡尔算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 最小生成树 2. 克鲁斯卡尔算法介绍 3 ...
随机推荐
- 【转】Linux 概念架构的理解
转:http://mp.weixin.qq.com/s?__biz=MzA3NDcyMTQyNQ==&mid=400583492&idx=1&sn=3b18c463dcc451 ...
- 关于js中的几个小问题。
问题1: 使用连续赋值后面的变量会成为全局对象的一个属性,并且这个属性可以通过delete删除. 原因:赋值语句是从右往左执行的,我们将10赋值给了c,但是c此时还声明,接着把c的返回值赋值给了b,但 ...
- Eclipse为Unity3d编写jar组件
Unity3d和Android的交互有两种方式: (1)使用Eclipse为Unity3d编写库,也就是jar包,然后导入到U3D中使用: (2)将Unity3d项目导出为Android项目,然后直接 ...
- codeforce Number of Ways(暴力)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...
- list2json
list2json方法 System.Web.Script.Serialization.JavaScriptSerializer serial = new System.Web.Script.Seri ...
- 《微信小程序七日谈》- 第三天:玩转Page组件的生命周期
<微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 前两篇 ...
- 妙味5:document.cookie 操作
本地环境中测试需要用fireFox,其它几个浏览器不行,服务器都可以测出正确结果 cookie特点: 1. 如登陆信息存储,同一论坛打开多个页面不用重复登陆,就是通过cookie来存取实现: 2. ...
- codevs4247奇特的生物 解析报告
4247 奇特的生物 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 科学家们最近发现了一种奇怪的生物,它们每天长大一岁 ...
- POI中getLastRowNum() 和getLastCellNum()的区别 hssfSheet.getLastRowNum();//最后一行行标,比行数小1 hssfSheet.getRow(k).getLastCellNum();//获取列数,比最后一列列标大1
hssfSheet.getLastRowNum();//最后一行行标,比行数小1 hssfSheet.getRow(k).getLastCellNum();//获取列数,比最后一列列标大1
- 数论 --- 费马小定理 + 快速幂 HDU 4704 Sum
Sum Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=4704 Mean: 给定一个大整数N,求1到N中每个数的因式分解个数的 ...