|
這是要介紹的最後一個遞迴繪圖,看起來很複雜,但其實只是程式碼長了一點,實際上並不會比雪花來得複雜,只要弄清楚繪圖順序就可以了。
在這邊只解釋單一樹木的基本繪圖方式,主要分為主幹與支幹的繪製,如下圖所示,其中標號表示頂點的前進順序:

接下來只要在主幹與支幹上不斷的繪製一定比例的相同圖形,就可以完成一顆樹,將這些樹排列起來就成為樹林,詳細的原始碼請看以下的程式,其中註解部份先不
用理會:
package onlyfun.caterpillar.graphics.recursive; import onlyfun.caterpillar.graphics.Turtle; import java.awt.*; import javax.swing.JApplet; public class Forest extends JApplet { private Turtle t; private double ang = 86.0, k1 = 1.5, k2 = 1.0, Leng = 2.0, k; public void init() { t = new Turtle(); k = 1.0/(k1+2*k2+2*(k1+k2)*Math.cos( Math.toRadians(ang))); setBackground(Color.black); } public void woods(double leng) { if(leng > Leng) { // Point p[] = new Point[3]; t.move(leng); t.warp(-leng);
/* 畫實心倒影 // 畫主幹 t.warp(k*k1*leng); p[0] = new Point((int)t.LPX, (int)t.LPY); t.turn(ang); t.warp(k*k1*leng); p[1] = new Point((int)t.LPX, (int)t.LPY); t.turn(-2*ang); t.warp(k*k1*leng); p[2] = new Point((int)t.LPX, (int)t.LPY); t.polygonF(p,3); // 畫右支幹 t.turn(ang); t.warp(k*leng); p[0] = new Point((int)t.LPX, (int)t.LPY); t.turn(ang); t.warp(k*k2*leng); p[1] = new Point((int)t.LPX, (int)t.LPY); t.turn(-2*ang); t.warp(k*k2*leng); p[2] = new Point((int)t.LPX, (int)t.LPY); t.polygonF(p,3); // 支幹退回 t.warp(-k*k2*leng); t.turn(2*ang); t.warp(-k*k2*leng); t.turn(-ang); t.warp(-k*leng); t.turn(-ang); // 主幹退回 t.warp(-k*k1*leng); t.turn(2*ang); t.warp(-k*k1*leng); t.turn(-ang); t.warp(-k*k1*leng); */ woods(k*k1*leng); t.turn(ang); woods(k*k1*leng); t.turn(-2*ang); woods(k*k1*leng); t.turn(ang); woods(k*leng); t.turn(ang); woods(k*k2*leng); t.turn(-2*ang); woods(k*k2*leng); t.turn(ang); woods(k*k2*leng); } else t.warp(leng); } public void paint(Graphics g) { g.setColor(Color.yellow); t.setGraphics(g); t.window(0, 0, getSize().width, getSize().height); t.view(0, 0, getSize().width, getSize().height); t.setpoint(10, getSize().height/2); t.setangle(0); woods(400); } }

如果將上例程式的註解符號去除,可以繪製樹林的倒影,繪製方法是大同小異,這邊是使用實心圖形來表示倒影,為了繪製實心圖形,在海龜繪圖法中加入繪製實心多邊形的方法polygonF,如下所示:
public void polygonF(Point tri[], int n) {
int[] xPoints = new int[n],
yPoints = new int[n];
for(int i = 0; i < n; i++) {
xPoints[i] = tri[i].x;
yPoints[i] = tri[i].y;
}
g.fillPolygon(xPoints, yPoints, n);
}
下圖為加上倒影後的繪圖成果:

到目前為止所介紹的遞迴繪圖都是在2D平面上,實際上遞迴繪圖在3D空間中也有相當的應用,不過複雜性也因維度的增加而複雜許多,如果有興趣,建議您研究一下 JAVA 2D/3D繪圖程式設計實例應用 書中的3D遞迴繪圖原始碼。
|