【Java】仿真山的初步绘画

递归在java中有着很重要的作用,我们可以通过递归来绘制仿真山。首先我们先通一个绘画曲线例子来明白仿真山的绘画方式。

曲线的样式如下:

这种曲线是通过改变两点之间中点的y坐标来实现的,先改变起点与终点之间中点的坐标,在改变将中点作为起点和终点与原来的终点和起点取中点,并不断重复这个过程,直到满足相应的条件跳出递归,代码如下:

public void drawBrokenLine(int x1,int y1,int x2,int y2,Graphics g){
        if(Math.abs(x1-x2)<10){
            g.drawLine(x1,y1,x2,y2);
            return;
        }
        int x=(x1+x2)/2;
        Random r=new Random();
        int y,m=Math.abs(x1-x2)/2;
        if(r.nextInt(2)==0) {
            y = r.nextInt(m) + (y1 + y2) / 2;
        }
        else{
            y= (y1 + y2) / 2-r.nextInt(m);
        }
        drawBrokenLine(x1,y1,x,y,g);
        drawBrokenLine(x2,y2,x,y,g);
    }

这里需要运用随机数来生成中点的y坐标,并且为了使线条平缓,这就要将随机数的值与进行绘画时两点的坐标联系起来,否则绘画出来的图案如下图:

这样画出来的曲线看起不就不顺滑。

仿真山的绘画过程与上述曲线绘画过程十分相像,仿真山是通过改变三角形的三边中点的坐标,此时三角形形成了四块三角形,再将这四块三角形重复上述步骤,直到满足条件,将三角形的三个点和三个中点进行连接,再将三个中点进行连接,过程如下:

执行的代码如下:

public void drawArtificialMountain(int x,int y,int x1,int y1,int x2,int y2,Graphics g){
        int x3=(x+x1)/2,x4=(x1+x2)/2,x5=(x+x2)/2,
                y3=(y1+y)/2,y4=(y1+y2)/2,y5=(y+y2)/2;
        if(Math.abs((x1-x)*(y2-y)-(y1-y)*(x2-x))/2<30){
            g.drawLine(x,y,x3,y3);
            g.drawLine(x3,y3,x2,y2);
            g.drawLine(x2,y2,x4,y4);
            g.drawLine(x4,y4,x1,y1);
            g.drawLine(x1,y1,x5,y5);
            g.drawLine(x5,y5,x,y);
            g.drawLine(x3,y3,x4,y4);
            g.drawLine(x4,y4,x5,y5);
            g.drawLine(x5,y5,x3,y3);
            return;
        }
        Random r=new Random();
        int m1=Math.abs(x-x2)+1;
        int m2=Math.abs(x1-x2)+1;
        int m3=Math.abs(x1-x)+1;
        if(r.nextInt(2)==0) {
            y3 = r.nextInt(m1)/3 + (y + y2) / 2;
            y4 = r.nextInt(m2)/3 + (y1 + y2) / 2;
            y5 = r.nextInt(m3)/3 + (y1 + y) / 2;
        }
        else{
            y3= (y + y2) / 2-r.nextInt(m1)/3;
            y4= (y1 + y2) / 2-r.nextInt(m2)/3;
            y5= (y1 + y) / 2-r.nextInt(m3)/3;
        }
        drawArtificialMountain(x,y,x5,y5,x3,y3,g);
        drawArtificialMountain(x5,y5,x1,y1,x4,y4,g);
        drawArtificialMountain(x3,y3,x4,y4,x2,y2,g);
        drawArtificialMountain(x4,y4,x3,y3,x5,y5,g);
    }

绘制的结果如下:

 

还有一些细节部分例如重写刷新方式和对执行动作的存储。首先创建一个类Shape,再在监听器接口中创建shape的动态数组存储绘画的图案,在重写刷新方式时调用。重写的刷新方式如下:

public class DrawJFrame extends JFrame {
    DrawMountainListener d1;
    public void paint(Graphics g){
        super.paint(g);
        for (int i = 0; i <= d1.shapeCount; i++) {
            Shape myShape = d1.shapeList[i];
            if (myShape == null) {
                return;
            }
            if(myShape.action.equals("折线图")) {
                d1.drawBrokenLine(myShape.x1, myShape.y1, myShape.x2, myShape.y2, myShape.g);
            }
            if(myShape.action.equals("仿真山")){
                int x=(d1.x1+d1.x2)/2;
                d1.drawArtificialMountain(x,myShape.y1,myShape.x1, myShape.y2, myShape.x2, myShape.y2, myShape.g);
            }
        }
    }
}

还有当绘画的图案超过一定的范围时就不进行绘画,例如在绘画曲线时图案超过绘画的范围,图案就会如下图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值