利用遞回實作山脈效果,填充山脈以及山脈顏色漸變
遞回山脈要求:
- 初始定義兩個點AB
- 取AB的中點P,讓中點的Y坐標在[-range,range]范圍內隨機取值,得到P點
- 要求每次迭代后range按比例rate縮小
- 分別取AP和PB,重復上述程序
- 遞回結束,連線
—————————————————————————————————————
public void mountain(Graphics g,int x1,int y1,int x2,int y2,int range,double rate){//定義山脈方法
if(Math.abs(x2-x1)<20){ //迭代退出條件
g.drawLine(x1,y1,x2,y2); //※【迭代結束,連接當前兩個點】
}else{
int x = (int)((x1+x2)/2); //P點橫坐標
int y = (int)((y1+y2)/2); //P點線性縱坐標
int Rnumber = (int)(Math.random()*(2*range)-range); //從-range到range隨機取值
int Nrange = (int)(range*rate); //每次迭代改變range的范圍
mountain(g,x1,y1,x,y+Rnumber,Nrange,rate);
mountain(g,x,y+Rnumber,x2,y2,Nrange,rate);
}
mountain(gr,0,500,1000,500,200,0.5);
效果如下:
如何填充山脈呢?要用到fillPolygon方法,我們來看下該方法的描述:
public void fillPolygon(Polygon p)
作用是填充一個多邊形,需要指定 Polygon 物件定義這個多邊形,
需要用到的方法是addPoint(int x;int y);
作用是將指定的坐標追加到此 Polygon物件,
public void mountain(Graphics g,int x1,int y1,int x2,int y2,int range,double rate){
if(Math.abs(x2-x1)<20){
g.drawLine(x1,y1,x2,y2); //在連線操作結束后填充
Polygon p = new Polygon(); //創建一個Polygon()類的物件,呼叫addPoint方法
p.addPoint(x1, y1);
p.addPoint(x1,1000);
p.addPoint(x2, 1000);
p.addPoint(x2, y2); //這里注意坐標的追加要逆時針
g.fillPolygon(p); //填充,g是畫筆物件
}else{
int x = (int)((x1+x2)/2);
int y = (int)((y1+y2)/2);
int Rnumber = (int)(Math.random()*(2*range)-range);
int Nrange = (int)(range*rate);
mountain(g,x1,y1,x,y+Rnumber,Nrange,rate);
mountain(g,x,y+Rnumber,x2,y2,Nrange,rate);
}
效果如下
由于此時還沒有定義顏色,所以填充是純黑效果
下一步我們要實作山脈的漸變,有兩種方式,一是每次畫完一個山脈后改變RGB的值,二是每次畫完一個山脈后改變透明度A的值,我們分別試下
- 改變R、G、B三值
public void mouseClicked(MouseEvent e) { //點擊方法
if ("遞回山脈".equals(type)){
Color c = new Color(r,g,b); //r,g,b我定義在全域變數,初始值均為20
gr.setColor(c); //給畫筆設定顏色
mountain(gr,0,500,1000,500,200,0.5);
r+=20; //迭代結束后改變r,g,b的值
g+=20;
b+=20;
}
效果如下
這種效果本質上還是純色填充,會重疊覆寫,于是我們可以去修改透明度的值
public void mouseClicked(MouseEvent e) { //點擊方法
if("遞回山脈".equals(type)){
Color c = new Color(r,g,b,a); //r、g、b、a均定義在全域變數,初值均為0,r、g、b三值為0時是純黑,a為0時全透明,為255時不透明
gr.setColor(c);
mountain(gr,0,500,1000,500,200,0.5);
a+=30;
}
效果如下
是不是有透視的感覺?
但是還有一個問題,第二種方法(改變透明度的操作)的回應速度比較慢,往往是滑鼠點擊后幾秒,才開始“慢悠悠”繪制山脈與填充,而且填充程序也是逐漸的,像影片一樣,
如何解決呢?java快取!!!
介紹一個簡易的快取
BufferedImage類是一個帶緩沖區影像類,主要作用是將一幅圖片加載到記憶體中(BufferedImage生成的圖片在記憶體里有一個影像緩沖區,利用這個緩沖區我們可以很方便地操作這個圖片),原理是系統在尚未執行畫的操作/代碼前,已經把影像畫在緩沖區,隨時呼叫,
步驟:
- 創建一個BufferedImage物件
- 獲取緩沖區的畫筆
- 將實作畫圖的代碼中的原畫筆物件改為緩沖區畫筆
- 用原畫筆物件呼叫drawImage方法
if("遞回山脈".equals(type)){
BufferedImage buffImage = new BufferedImage(1000,1000,BufferedImage.TYPE_INT_ARGB); //創建BufferedImage物件,前兩個引數為表單大小
Graphics buffG = buffImage.getGraphics(); //獲取緩沖區畫筆物件
Color c = new Color(r,g,b,a);
buffG.setColor(c); //將原畫筆物件改為緩沖區畫筆
mountain(buffG,0,500,1000,500,200,0.5); //將實作畫圖的代碼中的原畫筆物件改為緩沖區畫筆
a+=30;
gr.drawImage(buffImage, 0, 0,null); //用原畫筆畫出緩沖區圖片,中間兩個int值代表畫圖的起始點
}
效果就不展示了,確實可以瞬間畫出圖片,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/209402.html
標籤:其他
上一篇:心理學與生活 - 發展與教育
下一篇:二叉樹序列化和反序列化的兩種方式
