其实好久以前看人家画了好多分形,觉得很漂亮但是也只是套下公式而已;等到自己开始写了以后才发现“套公式”也没那么简单。
半个月前,做项目需要,开始画起来了分形。
1、第一个是在PPT上的,
也就是一个公式
xn+1=yn-sign(xn)|b xn-c|1/2
yn+1=a-xn 其中a=0.4,b=1,c=0;
在这中遇到的问题是,只能画出来几个点,不管你循环多少次,而且是负的。最后还是找到公式的原因,公式中应该是先取绝对值,再取开方的。代码如下、、、
double a=0.4,b=1,c=0;
double x1=0,y1=0,x2,y2;
int x,y,t1,t2,t3;
java.util.Random ram=new java.util.Random();
for(int i= 0;i<4000000;i++){
x2=y1-Math.signum(x1)*Math.sqrt(Math.abs(b*x1-c));
y2=a-x1;
x=(int)(x2*100)+350;
y=(int)(y2*100)+350;
x1=x2;
y1=y2;
t1=ram.nextInt(225);
t2=ram.nextInt(125)+100;
t3=ram.nextInt(225);
g.setColor(new Color(t1,t2,t1));
g.drawLine(x, y, x, y);
}
注:我在中间用了三个随机数来生成每个点的颜色,这就导致出来的图形五颜六色的像是在一闪一闪一样的。创新呀!!!!
2、下一个看到个树叶感觉不错,想画下了,但是公式给的是一组数据,具体说是上一个图形是那些a,b,c 参数都有固定的初始化值,这样出来的图形就固定了,但是这次给的是四组数据,每个里面的参数都是一样的,只是初始化值不一样。这就有问题了,这么多值该怎么去实例化、、、、耽误好久,最后还是问了别人说这里面有个p是代表的概率,这样就清除了,但是接下来怎么表示数据呢——我就想到了随机数,随机产生的数不就是概率么、、、这样就解决了。
代码如下:
double x3=0,x4,y3=0,y4,a ,b,c,d,e1,f;
int xx,yy;
for(int i=0;i<100000;i++){
java.util.Random ran=new java.util.Random();
int numbe=ran.nextInt(100)+1;
int t1=ran.nextInt(225);
int t2=ran.nextInt(225);
int t3=ran.nextInt(225);
g.setColor(new Color(t1,t2,t3));
if(numbe==1){
a = 0;
b=0;
c=0;
d=0.16;
e1=0;
f=0;
}else if(numbe>1&&numbe<=9){
a=0.2;
b=-0.26;
c=0.23;
d=0.22;
e1=0;
f=1.6;
}else if(numbe>9&&numbe<=16){
a=-0.15;
b=0.28;
c=0.26;
d=0.24;
e1=0;
f=0.44;
}else {
a=0.75;
b=0.04;
c=-0.04;
d=0.85;
e1=0;
f=1.6;
}
x4=a*x3+b*y3+e1;
y4=c*x3+d*y3+f;
xx=(int)(x4*(-30)+350);
yy=(int)(y4*(-30)+600);
x3=x4;
y3=y4;
g.drawLine(xx, yy, xx, yy);
3、后面碰到两个树也是更上面那个一样,也是参数随机的,只是他没给概率,这我就大胆自己随便设了几个概率就 画了两棵树
①double r,s3,theta,phi,e3,f,x1=0,x2,y1=0,y2;
int x,y;
java.util.Random ran=new java.util.Random();
for(int i=0;i<100000;i++){
int t1=ran.nextInt(225);
int t2=ran.nextInt(225);
int t3=ran.nextInt(225);
g.setColor(new Color(t1,t2,t3));
int numbe=ran.nextInt(100)+1;
if(numbe==1){
r = 0.0500;
s3=0.6000;
theta=0.0000;
phi=0.0000;
e3=0.0000;
f=0.0000;
}else if(numbe>1&&numbe<=9){
r = 0.0500;
s3=-0.5000;
theta=0.0000;
phi=0.0000;
e3=0.0000;
f=1.0000;
}else if(numbe>9&&numbe<=16){
r = 0.6000;
s3=0.5000;
theta=0.6980;
phi=0.6980;
e3=0.0000;
f=0.6000;
}else if(numbe>16&&numbe<=40){
r = 0.5000;
s3=0.4500;
theta=0.3490;
phi=0.3492;
e3=0.0000;
f=1.1000;
}else if(numbe>40&&numbe<=70){
r = 0.5000;
s3=0.5500;
theta=-0.5240;
phi=-0.5240;
e3=0.0000;
f=1.0000;
}else {
r =0.5500;
s3=0.4000;
theta=-0.6980;
phi=-0.6980;
e3=0.000;
f=0.7000;
}
x2=r*Math.cos(theta)*x1-s3*(Math.sin(phi))*y1+e3;
y2=r*Math.sin(theta)*x1+s3*Math.cos(phi)*y1+f;
x=(int)(x2*100)+400;
y=(int)(y2*100)+400;
x1=x2;
y1=y2;
g.drawLine(x, y, x, y);
}
②:
double a,b,c,d,e4,f,x1=0,x2,y1=0,y2;
int x,y;
java.util.Random rem=new java.util.Random();
for(int i=0;i<1000000;i++){
int tt=rem.nextInt(9)+1;
if(tt>=1&&tt<=8){
a=0.824074 ;
b=0.281428 ;
c=-0.212346;
d=0.864198 ;
e4=-1.882290;
f=-0.110607;
}else {
a=0.088272 ;
b=0.520988 ;
c=-0.463889;
d=-0.377778 ;
e4=0.785360;
f=8.095795;
}
x2=a*x1+b*y1+e4;
y2=c*x1+d*y1+f;
x=(int)(40*x2+300);
y=(int)(40*y2+300);
x1=x2;
y1=y2;
int t1=rem.nextInt(225);
int t2=rem.nextInt(225);
int t3=rem.nextInt(225);
g.setColor(new Color(t1,t2,t3));
g.drawLine(x, y, x, y);
}
4、接下来这个是我在网上看到的,他有改变一个参数就可以变化出好多种不同的形状,特别好看,而且这个跟我们的项目主题比较相符,所有果断选择了去研究它,在这遇到几个比较头疼的问题
①他没给x,y的初始值,正常情况下这没给的就是从0开始,但是他给的公式就是如果一开始是0的话接下来所有的都是0,我就问了别人,答案都是不知道、、、、、好吧,好几次想着烦了就没弄了。最后有一次突然想到,前几个分形都和概率有关,那这个是不是也跟概率有关,所有我尝试着用随机数去生成初始的x,y,结果确实有图形出来了。
②但是这个出来也就仅仅是个轮廓,这样就不会弄了,后来上课问了强哥,强哥也说没画过,结果强哥愣是照着那个作者给的c代码敲了一遍,果然出来了。这是强哥的代码
double x1=0,x2,y1=0,y2,a=1.57;
int x,y;
double r = 0;
int nnew = 0;
Random random = new Random();
int N = 600000;
int NX = 2000;
int NY = 2000;
int SCALE = NX/3;
for(int i=0;i<N;i++){
r = x1*x1+y1*y1;
if (r > 1e32 || i % (N/1000) == 0) {
x1 = 2*random.nextDouble() - 1;
y1= 2*random.nextDouble() - 1;
nnew = 0;
}
x2=x1*Math.cos(a)-(y1-x1*x1)*Math.sin(a);
y2=x1*Math.sin(a)+(y1-x1*x1)*Math.cos(a);
if (nnew > 10) { // Found the attractor
x = (int)(x2 * SCALE + NX/2); // Mapping to pixel coordinates
y = (int)(y2 * SCALE + NY/2);
x -= 200;
x /= 2;
y /= 2;
g.drawLine(x, y, x, y);
}
x1=x2;
y1=y2;
nnew++;
}
说实话我没怎么看懂、、、、、
但是我自己在和强哥交流的时候突然想到,我用随机数画出来的是一个轮廓,而原图有是由很多轮廓组成,那我能不能再那个循环随机数外面再加一个循环,这不就有可能出来么、、、所有我果断用自己的想法敲了一遍 结果还真出来了 !!这是我的代码
double x1,x2,y1,y2,a=2.2;
int x,y;
java.util.Random ram=new java.util.Random();
for(int i=0;i<1000;i++){
x1 = 2*ram.nextDouble() - 1;
y1=2*ram.nextDouble() - 1;
int r1=ram.nextInt(225);
int r2=ram.nextInt(225);
int r3=ram.nextInt(225);
g.setColor(new Color(r1,r2,r3));
for(int j=0;j<1000;j++){
x2=x1*Math.cos(a)-(y1-x1*x1)*Math.sin(a);
y2=x1*Math.sin(a)+(y1-x1*x1)*Math.cos(a);
x=(int)(x2*2000/3+900);
y=(int)(y2*2000/3+800);
x-=200;
x/=2;
y/=2;
x1=x2;
y1=y2;
g.drawLine(x, y, x, y);
}
}
感觉比上面那个简洁多了、、哈哈 好有成就感!!
总的感觉一个人想太容易陷进去,即使跟别人交流也得多找几个,因为好多人看到的都是差不多,关键要听听那些不同思路的,这样容易有突破。
半个月前,做项目需要,开始画起来了分形。
1、第一个是在PPT上的,
也就是一个公式
xn+1=yn-sign(xn)|b xn-c|1/2
yn+1=a-xn 其中a=0.4,b=1,c=0;
在这中遇到的问题是,只能画出来几个点,不管你循环多少次,而且是负的。最后还是找到公式的原因,公式中应该是先取绝对值,再取开方的。代码如下、、、
double a=0.4,b=1,c=0;
double x1=0,y1=0,x2,y2;
int x,y,t1,t2,t3;
java.util.Random ram=new java.util.Random();
for(int i= 0;i<4000000;i++){
x2=y1-Math.signum(x1)*Math.sqrt(Math.abs(b*x1-c));
y2=a-x1;
x=(int)(x2*100)+350;
y=(int)(y2*100)+350;
x1=x2;
y1=y2;
t1=ram.nextInt(225);
t2=ram.nextInt(125)+100;
t3=ram.nextInt(225);
g.setColor(new Color(t1,t2,t1));
g.drawLine(x, y, x, y);
}
注:我在中间用了三个随机数来生成每个点的颜色,这就导致出来的图形五颜六色的像是在一闪一闪一样的。创新呀!!!!
2、下一个看到个树叶感觉不错,想画下了,但是公式给的是一组数据,具体说是上一个图形是那些a,b,c 参数都有固定的初始化值,这样出来的图形就固定了,但是这次给的是四组数据,每个里面的参数都是一样的,只是初始化值不一样。这就有问题了,这么多值该怎么去实例化、、、、耽误好久,最后还是问了别人说这里面有个p是代表的概率,这样就清除了,但是接下来怎么表示数据呢——我就想到了随机数,随机产生的数不就是概率么、、、这样就解决了。
代码如下:
double x3=0,x4,y3=0,y4,a ,b,c,d,e1,f;
int xx,yy;
for(int i=0;i<100000;i++){
java.util.Random ran=new java.util.Random();
int numbe=ran.nextInt(100)+1;
int t1=ran.nextInt(225);
int t2=ran.nextInt(225);
int t3=ran.nextInt(225);
g.setColor(new Color(t1,t2,t3));
if(numbe==1){
a = 0;
b=0;
c=0;
d=0.16;
e1=0;
f=0;
}else if(numbe>1&&numbe<=9){
a=0.2;
b=-0.26;
c=0.23;
d=0.22;
e1=0;
f=1.6;
}else if(numbe>9&&numbe<=16){
a=-0.15;
b=0.28;
c=0.26;
d=0.24;
e1=0;
f=0.44;
}else {
a=0.75;
b=0.04;
c=-0.04;
d=0.85;
e1=0;
f=1.6;
}
x4=a*x3+b*y3+e1;
y4=c*x3+d*y3+f;
xx=(int)(x4*(-30)+350);
yy=(int)(y4*(-30)+600);
x3=x4;
y3=y4;
g.drawLine(xx, yy, xx, yy);
3、后面碰到两个树也是更上面那个一样,也是参数随机的,只是他没给概率,这我就大胆自己随便设了几个概率就 画了两棵树
①double r,s3,theta,phi,e3,f,x1=0,x2,y1=0,y2;
int x,y;
java.util.Random ran=new java.util.Random();
for(int i=0;i<100000;i++){
int t1=ran.nextInt(225);
int t2=ran.nextInt(225);
int t3=ran.nextInt(225);
g.setColor(new Color(t1,t2,t3));
int numbe=ran.nextInt(100)+1;
if(numbe==1){
r = 0.0500;
s3=0.6000;
theta=0.0000;
phi=0.0000;
e3=0.0000;
f=0.0000;
}else if(numbe>1&&numbe<=9){
r = 0.0500;
s3=-0.5000;
theta=0.0000;
phi=0.0000;
e3=0.0000;
f=1.0000;
}else if(numbe>9&&numbe<=16){
r = 0.6000;
s3=0.5000;
theta=0.6980;
phi=0.6980;
e3=0.0000;
f=0.6000;
}else if(numbe>16&&numbe<=40){
r = 0.5000;
s3=0.4500;
theta=0.3490;
phi=0.3492;
e3=0.0000;
f=1.1000;
}else if(numbe>40&&numbe<=70){
r = 0.5000;
s3=0.5500;
theta=-0.5240;
phi=-0.5240;
e3=0.0000;
f=1.0000;
}else {
r =0.5500;
s3=0.4000;
theta=-0.6980;
phi=-0.6980;
e3=0.000;
f=0.7000;
}
x2=r*Math.cos(theta)*x1-s3*(Math.sin(phi))*y1+e3;
y2=r*Math.sin(theta)*x1+s3*Math.cos(phi)*y1+f;
x=(int)(x2*100)+400;
y=(int)(y2*100)+400;
x1=x2;
y1=y2;
g.drawLine(x, y, x, y);
}
②:
double a,b,c,d,e4,f,x1=0,x2,y1=0,y2;
int x,y;
java.util.Random rem=new java.util.Random();
for(int i=0;i<1000000;i++){
int tt=rem.nextInt(9)+1;
if(tt>=1&&tt<=8){
a=0.824074 ;
b=0.281428 ;
c=-0.212346;
d=0.864198 ;
e4=-1.882290;
f=-0.110607;
}else {
a=0.088272 ;
b=0.520988 ;
c=-0.463889;
d=-0.377778 ;
e4=0.785360;
f=8.095795;
}
x2=a*x1+b*y1+e4;
y2=c*x1+d*y1+f;
x=(int)(40*x2+300);
y=(int)(40*y2+300);
x1=x2;
y1=y2;
int t1=rem.nextInt(225);
int t2=rem.nextInt(225);
int t3=rem.nextInt(225);
g.setColor(new Color(t1,t2,t3));
g.drawLine(x, y, x, y);
}
4、接下来这个是我在网上看到的,他有改变一个参数就可以变化出好多种不同的形状,特别好看,而且这个跟我们的项目主题比较相符,所有果断选择了去研究它,在这遇到几个比较头疼的问题
①他没给x,y的初始值,正常情况下这没给的就是从0开始,但是他给的公式就是如果一开始是0的话接下来所有的都是0,我就问了别人,答案都是不知道、、、、、好吧,好几次想着烦了就没弄了。最后有一次突然想到,前几个分形都和概率有关,那这个是不是也跟概率有关,所有我尝试着用随机数去生成初始的x,y,结果确实有图形出来了。
②但是这个出来也就仅仅是个轮廓,这样就不会弄了,后来上课问了强哥,强哥也说没画过,结果强哥愣是照着那个作者给的c代码敲了一遍,果然出来了。这是强哥的代码
double x1=0,x2,y1=0,y2,a=1.57;
int x,y;
double r = 0;
int nnew = 0;
Random random = new Random();
int N = 600000;
int NX = 2000;
int NY = 2000;
int SCALE = NX/3;
for(int i=0;i<N;i++){
r = x1*x1+y1*y1;
if (r > 1e32 || i % (N/1000) == 0) {
x1 = 2*random.nextDouble() - 1;
y1= 2*random.nextDouble() - 1;
nnew = 0;
}
x2=x1*Math.cos(a)-(y1-x1*x1)*Math.sin(a);
y2=x1*Math.sin(a)+(y1-x1*x1)*Math.cos(a);
if (nnew > 10) { // Found the attractor
x = (int)(x2 * SCALE + NX/2); // Mapping to pixel coordinates
y = (int)(y2 * SCALE + NY/2);
x -= 200;
x /= 2;
y /= 2;
g.drawLine(x, y, x, y);
}
x1=x2;
y1=y2;
nnew++;
}
说实话我没怎么看懂、、、、、
但是我自己在和强哥交流的时候突然想到,我用随机数画出来的是一个轮廓,而原图有是由很多轮廓组成,那我能不能再那个循环随机数外面再加一个循环,这不就有可能出来么、、、所有我果断用自己的想法敲了一遍 结果还真出来了 !!这是我的代码
double x1,x2,y1,y2,a=2.2;
int x,y;
java.util.Random ram=new java.util.Random();
for(int i=0;i<1000;i++){
x1 = 2*ram.nextDouble() - 1;
y1=2*ram.nextDouble() - 1;
int r1=ram.nextInt(225);
int r2=ram.nextInt(225);
int r3=ram.nextInt(225);
g.setColor(new Color(r1,r2,r3));
for(int j=0;j<1000;j++){
x2=x1*Math.cos(a)-(y1-x1*x1)*Math.sin(a);
y2=x1*Math.sin(a)+(y1-x1*x1)*Math.cos(a);
x=(int)(x2*2000/3+900);
y=(int)(y2*2000/3+800);
x-=200;
x/=2;
y/=2;
x1=x2;
y1=y2;
g.drawLine(x, y, x, y);
}
}
感觉比上面那个简洁多了、、哈哈 好有成就感!!
总的感觉一个人想太容易陷进去,即使跟别人交流也得多找几个,因为好多人看到的都是差不多,关键要听听那些不同思路的,这样容易有突破。