前言
整这个山脉花了我好长时间,最开始老师给我提出这个课题的时候大概是5天前吧,开始的时候想了一段时间,没想出来,结果落下了。中间断了几天搞学校的事儿去了,今天晚上又去上课了解了一下,再参考了一下学长的代码才终于整了出来,并且在途中还弄出了一些意想不到的结果(图像还是挺有趣的,就是不知道原理是什么)
先上几张我做的过程中的图吧
这是第一次的,直接做成对称心率了。。。
第二次,线条不连接,但是有勒味儿了
这就是意外的结果,老师说比要求做的还好,还让我把代码发给他,实际上我是懵逼的,为啥会出现这种,我也不知道啊。这个确实解释不了
这是最后的成果,反而觉得了无生趣了
然后我又将前面的图像代码相互重合,结果形成了这样的结果
以及这样。。。
后面两个出现了断层,看上去像是几张图拼起来的,就很神奇。。。
上代码,看方法
说实在的,上面的结果我所能解释的就是画线和心率图,后面的确实不知道是怎么出来的。(希望编程大佬能够指点指点我)
看着图像这么复杂,实际上几个递归就能解决问题
问题分析
我们先考虑简单点的,山嘛,就是起起落落,但是起落幅度不大。我们只需要先确定两个点,取其x轴中点,为了体现起伏感,y轴取中点的同时还要加一个随机值,这里要考虑一个问题,若是随机值一直是同一个范围,点与点之间的差距就会很大,最后会形成尖刺状,所以要将取值范围随递归按比例缩小。这就是全部的问题,先例出来,后面一一展示。
取随机值,并取缩小率
java中有取随机值的包,所以我们之间引入,并创建对象。
import java.util.Random;
Random rand = new Random();//我们将随机值命名为rand
double range=(rand.nextInt(1080)-540)*k;//随机值的初始取值范围约为-540到540
k*=0.5;//k的值决定了起伏程度,k的初始值为1
这里解释一下随机值的取值范围,
rand.nextInt(1080)呢,会取0到1079的值,我们减去之间值540,随机值取0的时候range就是-540,取1079时就是539(我的电脑屏幕y轴最大为1080)
值得注意的是k的取值,它决定了线条的起伏程度,这个值要取好,否则会很突兀,感兴趣的朋友可以试一试。
取中值
我们首先确定两个点x1,y1(0,540)和x2,y2(1920,540)分别位于屏幕左右两侧的中点,记录中点x0=(x1+x2)/2,y0=(y1+y2)/2+range。这里y0的range是必须要加的,否则就没有起伏了,成为一条直线。
double x0=(x1+x2)/2;
double y0=(y1+y2)/2;
走循环,用递归
接下来只要递归就完事儿了
draw1(g,(int)x1,(int)y1,(int)x0,(int)y0,depth-1,k);
draw1(g,(int)x0,(int)y0,(int)x2,(int)y2,depth-1,k);
注意,这里的递归有两个一个是画以左边为基础的线,另一个是画右边的线,我试了一下,只用一个递归会出现只运行不画线的情况。
完整代码
public void draw1(Graphics g,int x1,int y1,int x2,int y2,int depth,double k) {
//depth代表递归等级
Random rand = new Random();
if(depth>1) {
double range=(rand.nextInt(1080)-540)*k;
double x0=(x1+x2)/2;
double y0=(y1+y2)/2+range;
k*=0.5;
draw1(g,(int)x1,(int)y1,(int)x0,(int)y0,depth-1,k);
draw1(g,(int)x0,(int)y0,(int)x2,(int)y2,depth-1,k);
// draw1(g,(int)x1,(int)(y1+range),(int)x0,(int)y0,depth-1,k);
// draw1(g,(int)x0,(int)y0,(int)x2,(int)(y2+range),depth-1,k);//两个为一组,不同组的效果不同,也可以结合,会出现抽象的3D山脉
// draw1(g,(int)x1,(int)(y1+range),(int)x0,(int)(y0+range),depth-1,k);//画抽象山脉时递归等级不能过大,否则会运算很久
// draw1(g,(int)x0,(int)(y0+range),(int)x2,(int)(y2+range),depth-1,k);
}
else {
g.drawLine((int)x1, (int)y1, (int)x2, (int)y2);//递归等级设置为10
}
}
if(btnstr.equals("分形山脉")) {
draw1(g,0,540,1920,540,10,1);
}
小结
以上就是对分形山脉的粗略解释,里面有很多我还未解决的问题,希望自己能够在以后的学习中逐渐领悟,也希望有大佬来为我指点。这里省略了画图板的制作,如果以后有时间的话会补上,写画图板的话又会有好多内容,不知道以后有没有时间咯。