Java實現遞歸山脈

本文實例為大傢分享瞭Java實現遞歸山脈的具體代碼,供大傢參考,具體內容如下

一、遞歸山脈的要求

給定左右兩個點X1(Lx,Ly),X2(Rx,Ry),一個y軸動態范圍-range~range,在該動態范圍內隨機選取一個數num,選取一個中點M,中點的橫坐標為(Lx+Rx)/2,縱坐標為(Ly+Ry)/2+num,連接左端點與中點、中點與右端點。如此反復,再分別取左端點X1和中點M的中點、中點M和右端點X2的中點,range范圍按一定比例縮小,連接兩點形成遞歸山脈。

二、創新點

之前我們調用遞歸的時候每循環一次都調用一次,後面的結果覆蓋前面的結果,形成最後的效果,這造成瞭之前的畫的一些圖的冗餘。在本次項目中,我們采用不一樣的思想,在循環部分隻做計算,當最終條件滿足時再畫圖,這樣就是最後每一小段之間連接,不會造成小段覆蓋大段的冗餘。

三、實現過程

(1)創建界面,綁定監聽

package com.yzd1223.RecurMountain;

import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JFrame;

public class RecurMountain {
    public void ShowUI() {
        JFrame jf = new JFrame("MyPad");
        jf.setSize(800, 600);//畫板寬800  高600
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        FlowLayout flayout = new FlowLayout();//設定流式佈局
        jf.setLayout(flayout);
        jf.setVisible(true);//實現窗體可視化
        
        DrawListener dlistener = new DrawListener();
        jf.addMouseListener(dlistener);//界面註冊鼠標監聽器
        
        Graphics g = jf.getGraphics();//得到窗體畫筆
        dlistener.g=g;//將窗體畫筆賦給監聽畫筆
    }
    
    public static void main(String[] args) {//主函數
        RecurMountain Rmountain = new RecurMountain();
        Rmountain.ShowUI();
    }

}

(2)鼠標釋放時畫出遞歸山脈

package com.yzd1223.RecurMountain;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

public class DrawListener implements MouseListener{
    Graphics g = null;
    int Lx,Ly,Rx,Ry;
    int range;
    double rate;
    
    @Override    //鼠標點擊
    public void mouseClicked(MouseEvent e) {
        
    }

    @Override    //鼠標按下  
    public void mousePressed(MouseEvent e) {
        
    }

    @Override    //鼠標釋放
    public void mouseReleased(MouseEvent e) {
        Lx=0;Ly=300;Rx=800;Ry=300;//初始左、右兩端點坐標
        range=150;//生成-range~range的動態取值空間
        rate=0.5;//range縮小比例
        MyRecurMountain(Lx,Ly,Rx,Ry,range,rate);//調用方法,畫遞歸山脈
        
    }

    @Override    //鼠標進入
    public void mouseEntered(MouseEvent e) {
        
    }

    @Override    //鼠標退出
    public void mouseExited(MouseEvent e) {
        
    }
    
    //自定義畫遞歸山脈圖方法
    public void MyRecurMountain(int Lx,int Ly,int Rx,int Ry,int range,double rate) {

        if(Math.abs(Rx-Lx)<1 | range==0) {
            g.drawLine(Lx, Ly, Rx, Ry);
            Polygon pon = new Polygon();//利用多邊形給畫的山脈填充顏色    順時針和逆時針可以   本次采用順時針
            pon.addPoint(Lx, Ly);
            pon.addPoint(Rx, Ry);
            pon.addPoint(Rx, 600);
            pon.addPoint(Lx, 600);
            g.setColor(new Color(0,150,30,20));//設置顏色
            g.fillPolygon(pon);//填充
        }else {//隻做計算
            int Mx=(Lx+Rx)/2;//中點坐標
            int My=(Ly+Ry)/2;
            Random rand = new Random();
            int num=rand.nextInt(range*2)-range;//隨機生成-150~150的動態范圍
            range = (int)(range*rate);//range范圍不斷縮小
            
            MyRecurMountain(Lx,Ly,Mx,My+num,range,rate);//與左端點遞歸
            MyRecurMountain(Mx,My+num,Rx,Ry,range,rate);//與右端點遞歸
            
        }
    }

}

在該段代碼中我們在else部分中對坐標進行計算,隨機生成num,並按rate比例縮小range,然後調用自己MyRecurMountain,直到滿足條件Math.abs(Rx-Lx)<1 | range==0,執行連線g.drawLine(Lx, Ly, Rx, Ry)。
在這裡我們還對圖像進行瞭填充,創建一個Polygon對象pon,將連線的兩點以及他們對應x坐標位於屏幕底部的點連接,形成一個封閉圖像,對該封閉圖形進行連接填充顏色。

Polygon pon = new Polygon();//利用多邊形給畫的山脈填充顏色    順時針和逆時針可以   本次采用順時針
            pon.addPoint(Lx, Ly);//左端點
            pon.addPoint(Rx, Ry);//右端點
            pon.addPoint(Rx, 600);//右端點屏幕底部點
            pon.addPoint(Lx, 600);//左端點屏幕底部點
            g.setColor(new Color(0,150,30,20));//設置顏色
            g.fillPolygon(pon);//填充

形成的效果如圖:

四、加緩沖提高畫圖速度

在之前的程序執行過程中,我們發現畫圖很慢,於是我們想改進畫圖速度。
是Image的一個子類,BufferedImage的主要作用就是將一副圖片加載到內存中。BufferedImage生成的圖片在內存裡有一個圖像緩沖區,利用這個緩沖區我們可以很方便的操作這個圖片,通常用來做圖片修改操作如大小變換、圖片變灰、設置圖片透明或不透明等,並且實現速度很快。

public void mouseReleased(MouseEvent e) {
  Lx=0;Ly=300;Rx=800;Ry=300;
  range=150;//生成-range~range的動態取值空間
  rate=0.5;//range縮小比例
  //創建緩沖圖片  大小和窗體一致  類型為RGB
  BufferedImage bufferedimage = new BufferedImage(800, 600, BufferedImage.TYPE_3BYTE_BGR);
  //得到緩存圖片的畫筆
  Graphics gr=bufferedimage.getGraphics();
  //將緩存圖片的畫筆一起傳入遞歸山脈畫圖的方法中
  //這樣在下一步將緩存圖片顯示的同時就能將遞歸山脈一起畫出   提高畫圖速度
  MyRecurMountain(Lx,Ly,Rx,Ry,gr,range,rate);
  //在畫板上將緩存圖片顯示出來
  g.drawImage(bufferedimage, 0, 0,800,600,null);
        
    }

我們在MouseReleased中創建一個和窗體大小一樣的RGB類型的bufferedimage對象,得到該對象的畫筆gr,將該畫筆作為畫遞歸山脈的畫筆傳入MyRecurMountain()方法中,最後將bufferedimage圖像顯示出來,這樣在顯示緩沖圖像的同時由於畫筆gr傳入瞭遞歸山脈方法中,遞歸山脈也能同時畫出,大大提高瞭畫圖速度,效果如下:

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: