您的位置:首页 > 其它

递归与分形图案

2016-07-07 17:46 302 查看
递归与分形
一、递归

1.什么是递归?

递归是函数(方法)自己调用自己。

多个函数相互调用,形成循环调用的过程。

例1:

methodA(){

methodA();

methodA();

methodA();

methodA();

}

例2:

methodA(){

methodB();

}

methodB(){

//代码

methodC();

}

methodC(){

//代码

methodB();

}

2.如果递归进入无限递归结果会怎样?

堆栈溢出(错误)

3.在定义递归的时候,必须要设置相应的条件:

1)递归必须要有退出条件

2.)解决同一类问题的集合。

注意: 递归在执行过程中,会不停的开辟内存空间存储数据,所以导致递归的性能非常差。

 

4.递归分为那几部分?

methodA(int i){

//代码1

methodA(i-1);

//代码2

}

while(true){

int i = 10;

}

前段:定义变量对象,计算操作,结束条件

后段:计算操作,返回结果

 

5.举例

斐波那契数列使用递归来实现

1,1,2,3,5,8,13,21,34,...

 

输出10个斐波那契数列,1和1不计算在内。

Fib(2) = Fib(1)+Fib(1)

Fib(3) = Fib(1)+Fib(2)[Fib(1)+Fib(1)]

Fib(5) = Fib(2)+Fib(3)[Fib(1)+Fib(2)]

public class Fib{
public static void main(String [] args){
Fib f = new Fib();
f.fib(1,1);
}
public void fib(int a,int b){
int i=1;
if(i>10)
return;
i++;
System.out.println(a+"\n"+b+"\n"+(a+b));
fib(a,a+b);
}
}

 

二、分形

分形是递归的应用,运用递归不断的循环,形成非常漂亮的图形。

1.三角形

三角形是先画一个三角形,然后不断的取三遍中点,不断的画,如此循环。

分为上方三角,左边三角,右边三角三个部分,三个递归

int a1,a2,b1,b2,c1,c2;
public void f1(int x1,int x2,int y1){
//画大三角形
int p1,p2,q1,q2,m1,m2,ab,n=3;
ab = Math.abs(x2-x1);
a1 = (x1+x2)/2;
a2 = y1-(int)(ab*Math.pow(3, 0.5)/2);
c1 = x1;
c2 = y1;
b1 = x2;
b2 = y1;
p1 = (a1+c1)/2;
p2 = (a2+c2)/2;
q1 = (a1+b1)/2;
q2 = (a2+b2)/2;
m1 = (b1+c1)/2;
m2 = (b2+c2)/2;
g.drawLine(a1,a2,b1,b2);
g.drawLine(b1,b2,c1,c2);
g.drawLine(c1,c2,a1,a2);
g.drawLine(p1,p2,q1,q2);
g.drawLine(q1,q2,m1,m2);
g.drawLine(m1,m2,p1,p2);
f11(p1,p2,q1,q2,m1,m2,n,a1,a2,b1,b2,c1,c2); //三边分开画:左、上、右
f12(p1,p2,q1,q2,m1,m2,n,a1,a2,b1,b2,c1,c2); /**注意:A,B,C定点也在变**/
f13(p1,p2,q1,q2,m1,m2,n,a1,a2,b1,b2,c1,c2);
}
public void f11(int p1,int p2,int q1,int q2,int m1,int m2,int n,int a1,int a2,int b1,int b2,int c1,int c2){
int P1,P2,Q1,Q2,M1,M2; /**注意:P,Q,M坐标在改变,但有些赋值需要用原有的值**/
if(n>0){
n--;
P1 = (p1+c1)/2;
P2 = (p2+c2)/2;
Q1 = (p1+m1)/2;
Q2 = P2;
M1 = (c1+m1)/2;
g.drawLine(P1,P2,Q1,Q2);
g.drawLine(Q1,Q2,M1,m2);
g.drawLine(M1,m2,P1,P2);
f11(P1,P2,Q1,Q2,M1,m2,n,a1,a2,b1,b2,c1,c2); //三边分开画:左C点、上A点、右B点
f12(P1,P2,Q1,Q2,M1,m2,n,p1,p2,b1,b2,c1,c2);
f13(P1,P2,Q1,Q2,M1,m2,n,a1,a2,m1,m2,c1,c2);
}
else
return;
//P,Q,M在f11,f12,f13中都是指三边中点,三个方向中间那个倒三角都是由这三个点画的,只是顶点或者是左右边的点不一样而已,所以方法括号里面都应该有这三个点
}
public void f12(int p1,int p2,int q1,int q2,int m1,int m2,int n,int a1,int a2,int b1,int b2,int c1,int c2){
int P1,P2,Q1,Q2,M1,M2;
if(n>0){
n--;
P1 = (p1+a1)/2;
P2 = (p2+a2)/2;
Q1 = (a1+q1)/2;
Q2 = P2;
M1 = (p1+q1)/2;
M2 = (p2+q2)/2;
g.drawLine(P1,P2,Q1,Q2);
g.drawLine(Q1,Q2,M1,M2);
g.drawLine(M1,M2,P1,P2);
f11(P1,P2,Q1,Q2,M1,M2,n,a1,a2,b1,b2,p1,p2); //三边分开画:左、上、右
f12(P1,P2,Q1,Q2,M1,M2,n,a1,a2,b1,b2,c1,c2);
f13(P1,P2,Q1,Q2,M1,M2,n,a1,a2,q1,q2,c1,c2);
}
else
return;
}
public void f13(int p1,int p2,int q1,int q2,int m1,int m2,int n,int a1,int a2,int b1,int b2,int c1,int c2){
int P1,P2,Q1,Q2,M1,M2;
if(n>0){
n--;
P1 = (q1+m1)/2;
P2 = (q2+m2)/2;
Q1 = (q1+b1)/2;
Q2 = P2;
M1 = (b1+m1)/2;
g.drawLine(P1,P2,Q1,Q2);
g.drawLine(Q1,Q2,M1,m2);
g.drawLine(M1,m2,P1,P2);
f11(P1,P2,Q1,Q2,M1,m2,n,a1,a2,b1,b2,m1,m2); //三边分开画:左、上、右
f12(P1,P2,Q1,Q2,M1,m2,n,q1,q2,b1,b2,c1,c2);
f13(P1,P2,Q1,Q2,M1,m2,n,a1,a2,b1,b2,c1,c2);
}
else
}




2.线段

也是分开左右两段画

int a;
public void f2(int x1,int y1,int x2,int y2){
a=Math.abs(x2-x1);
g.drawLine(x1, y1, x2, y1);
if(a>=2){
f21(x1,y1,x1+a/3,y1,a);//左右半段分开画
f22(x1+2*a/3,y1,x2,y1,a);}
else
return;
}
//画左半段
public void f21(int x1,int y1,int x2,int y2,int a){
a=Math.abs(x2-x1);
if(a>=2){
g.drawLine(x1, y1, x2, y1);
y1+=50;
f21(x1,y1,x1+a/3,y1,a);
f22(x1+2*a/3,y1,x2,y1,a);}
else
return;
}
//画右半段
public void f22(int x1,int y1,int x2,int y2,int a ){
a=Math.abs(x2-x1);
g.drawLine(x1, y1, x2, y1);
if(a>=2){
y1+=50;
f21(x1,y1,x1+a/3,y1,a);
else
return;
}



 

3.正方形

跟前面的差不多,不过是一个大的,旁边八个小的,然后分成八块循环

public void f3(int x1,int y1,int x2,int y2){
int height;
height = Math.abs(x2-x1);
int x,y,h,n = 3;
h = height/3;
x = x1 + h;
y = y1 + h;
g.drawRect(x1, y1, height, height);//注意:rect里的四个参数是左上角的两个坐标,和宽度高度!!!!!
//上面是画的最外边的大框,height是最大的外边
g.fillRect(x, y, h, h);
f31(x1,y1,x,y,h,n);
f32(x1,y1,x,y,h,n);
f33(x1,y1,x,y,h,n);
f34(x1,y1,x,y,h,n);
f35(x1,y1,x,y,h,n);
f36(x1,y1,x,y,h,n);
f37(x1,y1,x,y,h,n);
f38(x1,y1,x,y,h,n);
}
public void f31(int x1,int y1,int x,int y,int h,int n){//
int X,Y,H;
if(n>0){
n--;
H = h/3;
X = x1+H;
Y = y1+H;
g.fillRect(X, Y, H, H);
f31(x1,y1,x,y,H,n);
f32(x1,y1,x,y,H,n);
f33(x1,y1,x,y,H,n);
f34(x1,y1,x,y,H,n);
f35(x1,y1,x,y,H,n);
f36(x1,y1,x,y,H,n);
f37(x1,y1,x,y,H,n);
f38(x1,y1,x,y,H,n);
}
else
return;
}
public void f32(int x1,int y1,int x,int y,int h,int n){//s
int X,Y,H;
if(n>0){
n--;
x1 =x1+ h;
H = h/3;
X = x1+H;
Y = y1+H;
g.fillRect(X, Y, H, H);
f31(x1,y1,x,y,H,n);
f32(x1,y1,x,y,H,n);
f33(x1,y1,x,y,H,n);
f34(x1,y1,x,y,H,n);
f35(x1,y1,x,y,H,n);
f36
d27f
(x1,y1,x,y,H,n);
f37(x1,y1,x,y,H,n);
f38(x1,y1,x,y,H,n);
}
else
return;
}
public void f33(int x1,int y1,int x,int y,int h,int n){
int X,Y,H;
if(n>0){
n--;
x1 += 2*h;
H = h/3;
X = x1+H;
Y = y1+H;
g.fillRect(X, Y, H, H);
f31(x1,y1,x,y,H,n);
f32(x1,y1,x,y,H,n);
f33(x1,y1,x,y,H,n);
f34(x1,y1,x,y,H,n);
f35(x1,y1,x,y,H,n);
f36(x1,y1,x,y,H,n);
f37(x1,y1,x,y,H,n);
f38(x1,y1,x,y,H,n);
}
else
return;
}
public void f34(int x1,int y1,int x,int y,int h,int n){
int X,Y,H;
if(n>0){
n--;
y1 += h;
H = h/3;
X = x1+H;
Y = y1+H;
g.fillRect(X, Y, H, H);
f31(x1,y1,x,y,H,n);
f32(x1,y1,x,y,H,n);
f33(x1,y1,x,y,H,n);
f34(x1,y1,x,y,H,n);
f35(x1,y1,x,y,H,n);
f36(x1,y1,x,y,H,n);
f37(x1,y1,x,y,H,n);
f38(x1,y1,x,y,H,n);
}
else
return;
}
public void f35(int x1,int y1,int x,int y,int h,int n){
int X,Y,H;
if(n>0){
n--;
x1 += 2*h;
y1 += h;
H = h/3;
X = x1+H;
Y = y1+H;
g.fillRect(X, Y, H, H);
f31(x1,y1,x,y,H,n);
f32(x1,y1,x,y,H,n);
f33(x1,y1,x,y,H,n);
f34(x1,y1,x,y,H,n);
f35(x1,y1,x,y,H,n);
f36(x1,y1,x,y,H,n);
f37(x1,y1,x,y,H,n);
f38(x1,y1,x,y,H,n);
}
else
return;
}
public void f36(int x1,int y1,int x,int y,int h,int n){
int X,Y,H; /**注意:调用除自己以外的函数,记得修改参数值,可以先把其他函数注释**/
if(n>0){
n--;
y1 += 2*h;
H = h/3;
X = x1+H;
Y = y1+H;
g.fillRect(X, Y, H, H);
f31(x1,y1,x,y,H,n);
f32(x1,y1,x,y,H,n);
f33(x1,y1,x,y,H,n);
f34(x1,y1,x,y,H,n);
f35(x1,y1,x,y,H,n);
f36(x1,y1,x,y,H,n);
f37(x1,y1,x,y,H,n);
f38(x1,y1,x,y,H,n);
}
else
return;
}
public void f37(int x1,int y1,int x,int y,int h,int n){
int X,Y,H;
if(n>0){
n--;
x1 += h;
y1 += 2*h;
H = h/3;
X = x1+H;
Y = y1+H;
g.fillRect(X, Y, H, H);
f31(x1,y1,x,y,H,n);
f32(x1,y1,x,y,H,n);
f33(x1,y1,x,y,H,n);
f34(x1,y1,x,y,H,n);
f35(x1,y1,x,y,H,n);
f36(x1,y1,x,y,H,n);
f37(x1,y1,x,y,H,n);
f38(x1,y1,x,y,H,n);
}
else
return;
}
public void f38(int x1,int y1,int x,int y,int h,int n){
int X,Y,H;
if(n>0){
n--;
x1 += 2*h;
y1 += 2*h;
H = h/3;
X = x1+H;
Y = y1+H;
g.fillRect(X, Y, H, H);
f31(x1,y1,x,y,H,n);
f32(x1,y1,x,y,H,n);
f33(x1,y1,x,y,H,n);
f35(x1,y1,x,y,H,n);
f36(x1,y1,x,y,H,n);
f37(x1,y1,x,y,H,n);
f38(x1,y1,x,y,H,n);
}
else
return;
}




4.神奇的色子

原理:随机生成三个点abc和一个点p,然后随机获取三个点中的一个,取这个点和P点的中点,覆盖成新的p点,如此循环

int ax = random.nextInt(500);//nextInt()括号里的数字表示取值范围,这里是0-499
int ay = random.nextInt(500);
int bx = random.nextInt(500);
int by = random.nextInt(500);
int cx = random.nextInt(500);
int cy = random.nextInt(500);
int px = random.nextInt(500);
int py = random.nextInt(500);
int dx = 0, dy = 0;
g.setColor(color);
for (int i = 0; i < 10000; i++) {
// 随机获取A,B,C三个点中的一个
int index = random.nextInt(3);
// 根据随机获取的点和P点的中点来画黑
if (index == 0) {
dx = (ax + px) / 2;
dy = (ay + py) / 2;
}
if (index == 1) {
dx = (bx + px) / 2;
dy = (by + py) / 2;
}
if (index == 2) {
dx = (cx + px) / 2;
dy = (cy + py) / 2;
}

// 新画的点就要覆盖原来P点
g.drawLine(dx, dy, dx, dy);//画点
System.out.println(dx+","+dy);
px = dx;
py = dy;
}




5.陀螺形

迭代分形,运用公式

 


可以不断的改变abc的值,从而生成不同的图形,陀螺形是a = -2, b = -2, c = -1.2, d = 2


//
需要使用,类中的数学函数

double b=0 ,
d=0,
x = 0, y = 0;

for (int i = 0;
i < 10000;
i++) {

b = Math.sin(-2 *
y) - Math.cos(-2 *
x);

d = Math.sin(-1.2*
x) - Math.cos(2 *
y);

笔画图只能画int,所以要字符转换

int n = (int) (d * 100)+300;

g.setColor(new Color(n%200,n%223,n%155));

g.drawLine(m,
n, m,
n);

x =
b;

y =
d;

}

注意:调用公式时,变量一定要申明成double形式,再转换成int。

 


6.环形图案

与陀螺形相似,也是一个公式

 


当a = 1.40, b = 1.56, c = 1.40, d = -6.56

double b=0 ,
d=0,
x = 0, y = 0;

for (int i = 0;
i < 10000;
i++) {

b =-6.56* Math.sin(1.4*x) - Math.sin(1.56*y);

d = 1.4*Math.cos(1.4*
x) + Math.cos(1.56 *
y);

int m = (int) (b * 30)+200;

int n = (int) (d * 30)+200;

g.setColor(new Color(n%220,n%155,n%55));

g.drawLine(m,
n, m,
n);

x =
b;

y =
d;

}

 


7.渔网形

 


a = 0.4, b = 1, c = 0

 <img src="https://img-blog.csdn.net/20160707180155767?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
8.窗花形

跟4运用同一个公式,只不过a = 1, b = 4, c = 60

注意。4.5都是不断的在一直运行

 


 

9.

 


10

.


11.

 


关于颜色:

有两种方法

一是将面板竖着分成好几块,每一块设置不同的颜色渐变

Color color=g.getColor();
int red=color.getRed();
int blue=color.getBlue();
int green=color.getGreen();
if(dx<50){
red=255;
green=0;blue=0;
}
if(dx>50&&dx<100){
red=200;
green=100;blue=0;
}
if(dx>100&&dx<150){
red=155;
green=100;blue=50;
}
if(dx>150&&dx<200){
red=100;
blue=155;
green=100;
}
if(dx>200&&dx<250){
red=50;
blue=100;
green=255;
}
if(dx>250&&dx<300){
red=20;
blue=200;
green=255;
}
if(dx>300&&dx<350){
red=0;
blue=220;
green=255;
}
color=new Color(red,green,blue);
//color=new Color(250,i%255,i%155);
g.setColor(color);



可以看出

 

另一种是画笔调用的时候%某一个数字,如
g.setColor(new Color(n%220,n%155,n%55));

然后for循环的时候,因为每循环一次,n都是不同的,所以每次的颜色也不同,就形成了彩色,上面几个比较好看的图形都是用的这种方法,是不是很漂亮?

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: