绘制山脉

最近在绘制山脉,先来看看效果:

 虽然不是很好看,但至少从远方望去,山脉的那种感觉出来了,下面来看看是怎么做的:

绘制画图板很简单,这里就不多作叙述了。我们直接来看看山脉是怎么画的。

首先,我们需要确定一条长直线的起点和终点坐标,然后取这条直线的中点坐标,横坐标直接起点和终点的横坐标相加再除以二即可。至于纵坐标,为了实现山脉的效果,我们需要先确定某个值,然后以这个值为中心确定一个范围,纵坐标应该在这个范围内随机取值。然后,再分别取起点和这一点的中点以及这一点和终点的中点,再分别用递归来完成。

然后要注意,这个范围每次递归的时候都要按照一定的比例减小

等到递归结束的时候,再画直线,同时填充颜色。这样一来,绘制山脉的方法基本思路就确定了。

下面是绘制山脉的方法:

 1 public void drawMountains(int x1,int y1,int x2,int y2,double k,int times,Graphics g,Color c){
 2         Random rand = new Random();
 3         int range=0;
 4         if(times > 0){
 5             range = (int)((rand.nextInt(400)-200)*k);  //纵坐标取值的范围
 6             k*=0.5;   //缩小的比例
 7             int middleX = (x1+x2)/2; //中点横坐标
 8             int middleY = (y1+y2)/2 + range;  //中点纵坐标
 9             drawMountains(x1,y1,middleX,middleY,k,times-1,g,c);  //这里开始就是递归
10             drawMountains(middleX,middleY,x2,y2,k,times-1,g,c);
11         }else{
12             g.drawLine(x1,y1,x2,y2);  //递归结束,画直线
13             g.setColor(c);  //同时设置颜色
14             Polygon p1 = new Polygon();  //使用这个类来填充颜色
15             p1.addPoint(x1, 800);    
16             p1.addPoint(x1, y1);
17             p1.addPoint(x2, y2);
18             p1.addPoint(x2, 800);
19             Graphics2D g2 = (Graphics2D)g;
20             g2.fillPolygon(p1);
21         }
22     }

至于天空的颜色,我们可以在绘制画图板的时候就设置背景颜色。

下面来看完整代码:

Board.java:

 1 package Practice;
 2 
 3 import java.awt.Graphics;
 4 import javax.swing.JFrame;
 5 
 6 public class Board extends JFrame{
 7     public void paint(Graphics g){
 8         super.paint(g);
 9     }
10 }

Mountains.java:

 1 package Practice;
 2 
 3 import java.awt.Color;
 4 import java.awt.Graphics;
 5 import java.awt.Graphics2D;
 6 import java.awt.Polygon;
 7 import java.util.Random;
 8 import javax.swing.JFrame;
 9 
10 public class Mountains{
11 
12     public static void main(String[] args) {
13         Mountains m = new Mountains();
14         m.show();
15     }
16     
17     public void show(){
18         Board board = new Board();
19         board.setTitle("绘制山脉");
20         board.setSize(1200,800);
21         board.setLocationRelativeTo(null);
22         board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
23         board.setVisible(true);
24         try {
25             Thread.sleep(100);  //画图板也是绘制的,这里是为了等画图板全部绘制完成后再画山脉
26         } catch (InterruptedException e) {
27             // TODO Auto-generated catch block
28             e.printStackTrace();
29         }
30         Graphics g = board.getGraphics();
31         Color c1 = new Color(12,62,88);
32         Color c2 = new Color(14,70,101);
33         Color c3 = new Color(7,38,54);
34         g.setColor(new Color(109,191,235));
35         g.fillRect(0, 0, 1200, 800);
36         g.drawArc(100,40,90,50,0,180);  //这里画个太阳
37         g.setColor(Color.yellow); g.fillArc(100,100,40,40,0,-360);
38         drawMountains(0, 580, 1200, 580, 2,10,g,c3);
39         drawMountains(0, 580, 1200, 580, 2,10,g,c2);
40         drawMountains(0, 580, 1200, 580, 2,10,g,c1);
41     }
42     
43     public void drawMountains(int x1,int y1,int x2,int y2,double k,int times,Graphics g,Color c){
44         Random rand = new Random();
45         int range=0;
46         if(times > 0){
47             range = (int)((rand.nextInt(400)-200)*k);  //纵坐标取值的范围
48             k*=0.5;   //缩小的比例
49             int middleX = (x1+x2)/2; //中点横坐标
50             int middleY = (y1+y2)/2 + range;  //中点纵坐标
51             drawMountains(x1,y1,middleX,middleY,k,times-1,g,c);  //这里开始就是递归
52             drawMountains(middleX,middleY,x2,y2,k,times-1,g,c);
53         }else{
54             g.drawLine(x1,y1,x2,y2);  //递归结束,画直线
55             g.setColor(c);  //同时设置颜色
56             Polygon p1 = new Polygon();  //使用这个类来填充颜色
57             p1.addPoint(x1, 800);    
58             p1.addPoint(x1, y1);
59             p1.addPoint(x2, y2);
60             p1.addPoint(x2, 800);
61             Graphics2D g2 = (Graphics2D)g;
62             g2.fillPolygon(p1);
63         }
64     }
65 }

这样就可以啦!

 


 

 关于遇到的Bug:

首先,就是范围缩小的问题,特别注意这里k值一定要是double型!一开始我定义的k是整型的,但是这样一来,每次k×0.5的话,取整就变成0了,这样一来画出来不是山脉的效果,而是一条直线。

其次,是关于颜色的问题。因为这里在show方法里面调用了三次绘制山脉的方法,因此画出来有三条山脉,这里没有问题,但是天空的颜色,我刚开始是想画山脉的时候顺便就把天空颜色给画了。这样的话绘制山脉的方法里面我又添加了一个Color类型的参数,代表画天空的颜色。在画山脉颜色的时候,同时也利用Polygon这个类把山脉上方填充为天空的天蓝色。但是,因为有三座山,高度又是随机取值,一旦有一座山在横坐标相同情况下纵坐标取值比另一座山低,那么它的上面就会被填充成天蓝色,这样一来,上面那座山脉的颜色就被覆盖了,所以画出来只有一座山。然鹅解决方法很简单,只需要在最开始给整个绘图板画上天蓝色即可。

最后是一个不怎么算bug的bug,就是range取值,不要太大了。-400到400的范围就很好。

posted @ 2021-03-09 21:24  EvanTheBoy  阅读(526)  评论(0)    收藏  举报