Java實現(xiàn)遞歸山脈
本文實例為大家分享了Java實現(xiàn)遞歸山脈的具體代碼,供大家參考,具體內(nèi)容如下
一、遞歸山脈的要求
給定左右兩個點X1(Lx,Ly),X2(Rx,Ry),一個y軸動態(tài)范圍-range~range,在該動態(tài)范圍內(nèi)隨機選取一個數(shù)num,選取一個中點M,中點的橫坐標為(Lx+Rx)/2,縱坐標為(Ly+Ry)/2+num,連接左端點與中點、中點與右端點。如此反復,再分別取左端點X1和中點M的中點、中點M和右端點X2的中點,range范圍按一定比例縮小,連接兩點形成遞歸山脈。
二、創(chuàng)新點
之前我們調(diào)用遞歸的時候每循環(huán)一次都調(diào)用一次,后面的結(jié)果覆蓋前面的結(jié)果,形成最后的效果,這造成了之前的畫的一些圖的冗余。在本次項目中,我們采用不一樣的思想,在循環(huán)部分只做計算,當最終條件滿足時再畫圖,這樣就是最后每一小段之間連接,不會造成小段覆蓋大段的冗余。
三、實現(xiàn)過程
(1)創(chuàng)建界面,綁定監(jiān)聽
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();//設(shè)定流式布局 ?? ??? ?jf.setLayout(flayout); ?? ??? ?jf.setVisible(true);//實現(xiàn)窗體可視化 ?? ??? ? ?? ??? ?DrawListener dlistener = new DrawListener(); ?? ??? ?jf.addMouseListener(dlistener);//界面注冊鼠標監(jiān)聽器 ?? ??? ? ?? ??? ?Graphics g = jf.getGraphics();//得到窗體畫筆 ?? ??? ?dlistener.g=g;//將窗體畫筆賦給監(jiān)聽畫筆 ?? ?} ?? ? ?? ?public static void main(String[] args) {//主函數(shù) ?? ??? ?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的動態(tài)取值空間 ?? ??? ?rate=0.5;//range縮小比例 ?? ??? ?MyRecurMountain(Lx,Ly,Rx,Ry,range,rate);//調(diào)用方法,畫遞歸山脈 ?? ??? ? ?? ?} ?? ?@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));//設(shè)置顏色 ?? ??? ??? ?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的動態(tài)范圍 ?? ??? ??? ?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,然后調(diào)用自己MyRecurMountain,直到滿足條件Math.abs(Rx-Lx)<1 | range==0,執(zhí)行連線g.drawLine(Lx, Ly, Rx, Ry)。
在這里我們還對圖像進行了填充,創(chuàng)建一個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));//設(shè)置顏色 ?? ??? ??? ?g.fillPolygon(pon);//填充
形成的效果如圖:
四、加緩沖提高畫圖速度
在之前的程序執(zhí)行過程中,我們發(fā)現(xiàn)畫圖很慢,于是我們想改進畫圖速度。
是Image的一個子類,BufferedImage的主要作用就是將一副圖片加載到內(nèi)存中。BufferedImage生成的圖片在內(nèi)存里有一個圖像緩沖區(qū),利用這個緩沖區(qū)我們可以很方便的操作這個圖片,通常用來做圖片修改操作如大小變換、圖片變灰、設(shè)置圖片透明或不透明等,并且實現(xiàn)速度很快。
public void mouseReleased(MouseEvent e) { ??Lx=0;Ly=300;Rx=800;Ry=300; ??range=150;//生成-range~range的動態(tài)取值空間 ??rate=0.5;//range縮小比例 ??//創(chuàng)建緩沖圖片 ?大小和窗體一致 ?類型為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中創(chuàng)建一個和窗體大小一樣的RGB類型的bufferedimage對象,得到該對象的畫筆gr,將該畫筆作為畫遞歸山脈的畫筆傳入MyRecurMountain()方法中,最后將bufferedimage圖像顯示出來,這樣在顯示緩沖圖像的同時由于畫筆gr傳入了遞歸山脈方法中,遞歸山脈也能同時畫出,大大提高了畫圖速度,效果如下:
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java.net.MalformedURLException異常的解決方法
下面小編就為大家?guī)硪黄猨ava.net.MalformedURLException異常的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05淺談mybatis中的#和$的區(qū)別 以及防止sql注入的方法
下面小編就為大家?guī)硪黄獪\談mybatis中的#和$的區(qū)別 以及防止sql注入的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10SpringBoot面試突擊之過濾器和攔截器區(qū)別詳解
過濾器(Filter)和攔截器(Interceptor)都是基于?AOP(Aspect?Oriented?Programming,面向切面編程)思想實現(xiàn)的,用來解決項目中某一類問題的兩種“工具”,但二者有著明顯的差距,接下來我們一起來看2022-10-10Spring?Boot整合Log4j2.xml的問題及解決方法
這篇文章主要介紹了Spring?Boot整合Log4j2.xml的問題,本文給大家分享解決方案,需要的朋友可以參考下2023-09-09給JavaBean賦默認值并且轉(zhuǎn)Json字符串的實例
這篇文章主要介紹了給JavaBean賦默認值并且轉(zhuǎn)Json字符串的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03JSON序列化導致Long類型被搞成Integer的坑及解決
這篇文章主要介紹了JSON序列化導致Long類型被搞成Integer的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01