实验六分形图的生成
班级08信计二学号52 姓名刘丽杰分数
一、实验目的和要求:
1、掌握分形基本原理,熟悉分形的计算机模拟算法。
2、学习调试程序及分析运行结果。
3、上机操作迭代函数系统算法。
二、实验内容:
1、编程实现分形的贝塞尔算法,并输出图形。
2、编程实现一棵树,先按某一方向画一条直线段,然后在此线段上找到一系列节点,在每一节点处向左右偏转60度各画一条分支。
节点位置和节点处所画分支的长度的比值各按0.618分割。
三、程序执行和运行结果:
1、贝塞尔程序:
#include <graphics.h>
#include <conio.h>
#define WIDTH 640
#define HEIGHT 480
#define NUMPTS 6
HDC hdc;
float animpts[NUMPTS * 2];
float deltas[NUMPTS * 2];
void Init()
{
for (int i = 0; i < NUMPTS * 2; i += 2)
{
animpts[i ] = (float)rand() / RAND_MAX * WIDTH;
animpts[i + 1] = (float)rand() / RAND_MAX * HEIGHT;
deltas[i ] = (float)rand() / RAND_MAX * 4 + 2;
deltas[i + 1] = (float)rand() / RAND_MAX * 4 + 2;
if (animpts[i ] > WIDTH / 6.0f) deltas[i ] = -deltas[i ];
if (animpts[i + 1] > HEIGHT / 6.0f) deltas[i + 1] = -deltas[i + 1];
}
}
void Animate(float pts[], float deltas[], int index, int limit)
{
float newpt = pts[index] + deltas[index];
if (newpt <= 0)
{
newpt = -newpt;
deltas[index] = (float)rand() / RAND_MAX * 3 + 2;
}
else if (newpt >= (float)limit)
{
newpt = 2.0f * limit - newpt;
deltas[index] = -((float)rand() / RAND_MAX * 3 + 2);
}
pts[index] = newpt;
}
void Run()
{
int i;
for (i = 0; i < NUMPTS * 2; i += 2)
{
Animate(animpts, deltas, i , WIDTH);
Animate(animpts, deltas, i + 1, HEIGHT);
}
float* ctrlpts = animpts;
int len = NUMPTS * 2;
float prevx = ctrlpts[len - 2];
float prevy = ctrlpts[len - 1];
float curx = ctrlpts[0];
float cury = ctrlpts[1];
float midx = (curx + prevx) / 2.0f;
float midy = (cury + prevy) / 2.0f;
MoveToEx(hdc, (int)midx, (int)midy, NULL);
for (i = 2; i <= len; i += 2)
{
float x1 = (midx + curx) / 2.0f;
float y1 = (midy + cury) / 2.0f;
prevx = curx;
prevy = cury;
if (i < len)
{
curx = ctrlpts[i ];
cury = ctrlpts[i + 1];
}
else
{
curx = ctrlpts[0];
cury = ctrlpts[1];
}
midx = (curx + prevx) / 2.0f;
midy = (cury + prevy) / 2.0f;
float x2 = (prevx + midx) / 2.0f;
float y2 = (prevy + midy) / 2.0f;
POINT param[] = {(int)x1, (int)y1, (int)x2, (int)y2, (int)midx, (int)midy};
PolyBezierTo(hdc, param, 3);
}
}
void main()
{
initgraph(WIDTH, HEIGHT);
hdc = GetImageHDC();
Init();
BeginBatchDraw();
while (!kbhit())
{
cleardevice();
Run();
FlushBatchDraw();
Sleep(15);
}
EndBatchDraw();
getch();
closegraph();
}
运行结果:
2、程序:
#define g 0.618
#define PAI 3.1416
#include”graphics.h”
#include”math.h”
#include”stdio.h”
#include”conio.h”
float thita=6.0;
void grow(int x,int y,float lenth,float fai)
{
int x1,y1;
int nx,ny,count;
float nlenth;
x1=x+lenth*cos(fai*PAI/180.0);
y1=y-lenth*sin(fai*PAI/180.0);
line(x,y,x1,y1);
if(lenth<10)
return;
nlenth=lenth;
nx=x;
ny=y;
for(count=0;count<7;count++)
{
nx=nx+nlenth*(1-g)*cos(fai*PAI/180.0);
ny=ny-nlenth*(1-g)*sin(fai*PAI/180.0);
grow(nx,ny,nlenth*(1-g),fai+thita);
grow(nx,ny,nlenth*(1-g),fai-thita);
nlenth*=g;
}
}
void main()
{
int gm,gd;
detectgraph(&gd,&gm);
initgraph(&gd,&gm,””);
grow(300,300,280.0,90.0);
getch();
closegraph();
}
运行结果:
四、实验结果分析:
分形的对称性即表现了传统几何的上下、左右及中心对称。
同时它的自相似性又揭示了一种新的对称性,即画面的局部与更大范围的局部的对称,或说局部与整体的对称。
它是大小比例的对称,即系统中的每一元素都反映和含有整个系统的性质和信息。
从数学上来讲,曼德布洛特集合是一个复数的集合。
曼德布洛特集合就是使以上序列不延伸至无限大的所有c点的集合。
.Mandelbrot 集合图形的边界处,具有无限复杂和精细的结构。
如果计算机的精度是不受限制的话,可以无限地放大她的边界。
当放大某个区域,它的结构就在变化,展现出新的结构元素。
这正如前面提到的"蜿蜒曲折的一段海岸线",无论怎样放大它的局部,它总是曲折而不光滑,即连续不可微。
如果把所有不同的Julia 集重合起来,我们将会得到一个四维图形,它的其中两个维度是不同的初始值z 构成的复平面,另外两个维度则是不同的常数 c 构成的复平面。
这个四维空间就包含了所有不同的初始值在所有不同的常数 c 之下迭代的发散情况。
而Mandelbrot 集,则是这个四维图形在c = 0 处的一个切片,并且是最具有概括力的一个切片。
因此,我们相当于有了Mandelbrot 集的一个四维扩展,从这个四维图形中,我们可以切出很多二维的或者三维的切片,得到更多惊人而漂亮的图形。