L-System分形
部分与整体以某种形式相似的形,称为分形。即部分以相同的函数、不同某些变量,以某中确定的规则不断迭代或递归所画出整体的图形。
下面是分形的几个经典例子。
※※神奇的色子※※
1.平面上随机选A,B,C三个点。再随机选一个点,记为P。
2.有一个三面色子,每丢一次,则选中ABC三个中一点。
开始游戏:
1.重复丢色子,如果选中A,则取A和P的中点P1,画黑,
2.如果选中B,则取B和P1的中点P2,画黑
3.如果选中A,则取A和P2的中点P3,画黑
4….一直重复(如每点一下鼠标,丢10000次色子。
思路:为画图面板添加鼠标监听器方法,在鼠标释放的时候获取坐标值。收集上诉四个点的坐标值,其中前三个点分别为A,B,C,第四点位P。以一个0到2的随机数来确定A,B,C选中的点。每次计算选中点和P的中中点,以该中点替代P点。迭代。
public void mouseReleased(MouseEvent e) {
if(djf.buttonText().equals("色子")){
if(count==0){//第一次释放鼠标时获得A点坐标
x1=e.getX();
y1=e.getY();
count++;
}else if(count==1){//第二次释放鼠标时获得B点坐标
x2=e.getX();
y2=e.getY();
count++;
}else if(count==2){//第三次释放鼠标时获得C点坐标
x3=e.getX();
y3=e.getY();
count++;
}else if(count==3){//第四次释放鼠标时获得P点坐标
xp=e.getX();
yp=e.getY();
for(int i=0;i<100000;i++){//迭代100000次
Random r=new Random();
int n=r.nextInt(3);
switch(n){
case 0://选中A点
xp=(x1+xp)/2;
yp=(y1+yp)/2;//取AP中点,替代P点
g.setColor(new Color(yp/3,yp/4,yp/64));
g.drawLine(xp, yp, xp, yp);//画出该点
break;
case 1://选中B点
xp=(x2+xp)/2;
yp=(y2+yp)/2;//取BP中点,替代P点
g.setColor(new Color(yp/3,yp/4,yp/64));
g.drawLine(xp, yp, xp, yp);//画出该点
break;
case 2://选中C点
xp=(x3+xp)/2;
yp=(y3+yp)/2;//取CP中点,替代P点
g.setColor(new Color(yp/3,yp/4,yp/64));
g.drawLine(xp, yp, xp, yp);//画出该点
break;
}
}
count++;
}else if(count==4){
x1=y1=0;
x2=y2=0;
x3=y3=0;
count=0;
}
}
效果图如下:
※※美丽的窗花※※
迭代函数如下:(注意:sign为符号函数)
X(n+1)=Y(n)-sign(X(n))|bX(n)-c|^(1/2)
其中:a=1,b=4,c=60
public void chuanghua(){
x=x1;
y=y1;
double x2;
double y2;
double a=1;
double b=4;
double c=60;
for(int j=0;j<2000000;j++){
x2=y-Math.signum(x)*Math.sqrt(Math.abs(b*x-c));
y2=a-x;
x=x2;
y=y2;
if(j%3==0){
g.setColor(Color.red);
}
if(j%3==1){
g.setColor( Color.green);
}
if(j%3==2){
g.setColor( Color.blue);
}
g.drawLine((int)(x)+300,(int) (y)+250,(int)(x)+300,(int) (y)+250);
}
}
}
效果图如下:
若把系数稍作修改,则得到如下截然不同的图形:
double a=0.4;
double b=1;
double c=0;
※※逼真的树叶※※
熊哥推荐的站点:http://paulbourke.net/fractals/
http://paulbourke.net/fractals/ifs_fern_a/
好多图形都有迭代公式。比如:
以下是系数的选取。共有四组,每组取到的概率不相等,分别为0.01,0.07,0.07,0.85。以一个0到99的随机数指示取到的组别。
public void shuye(){
double a,b,c,d,ee,f;
double x5,y5,x52=0,y52=0;
for(int i=0;i<200000;i++){
Random rr=new Random();
int r=rr.nextInt(100);
if (r==0){
a=0;
b=0;
c=0;
d=0.16;
ee=0;
f=0;
}else if (r>=1&&r<=7) {
a=0.2;
b=-0.26;
c=0.23;
d=0.22;
ee=0;
f=1.6;
}else if (r>=8 && r<=14) {
a=-0.15;
b=0.28;
c=0.26;
d=0.24;
ee=0;
f=0.44;
}else{
a=0.85;
b=0.04;
c=-0.04;
d=0.85;
ee=0;
f=1.6;
}
x5=a*x52+b*y52+ee;
y5=c*x52+d*y52+f;
int tempx=-(int)(x5*50)+300;
int tempy=-(int)(y5*50)+550;
g.setColor(new Color(20,i/(200000/255),20));
g.drawLine(tempx,tempy,tempx,tempy);
x52=x5;
y52=y5;
}
}
效果图如下: