|
海龜繪圖法取名海龜並不是因為它的速度像烏龜,而是它繪圖的方式就像海龜前進的方式。
考慮海龜只能前進的情況(我也不知道海龜能不能倒著游?),在2D的情況下,也就是海龜只在一個XY平面運動的情況下,海龜的運動基本上只有前進與轉彎兩個動作,由此開始聯想,定出海龜繪圖法的幾個基本方法:
也就是將海龜直接放至某個(x, y)座標,而不進行任何的繪製動作。

由目前位置游至(x, y)位置,並在經過的路徑畫上直線。

無論海龜目前的頭朝向哪一個角度,由目前位置與角度游動L長度,並在經過的路徑上畫上直線。

角度的計算是以正X軸及頭所成的角度來計算。

即目前已成的角度 a 再加上θ,也就是與正X軸最後會成a+θ。

有了以上幾個基本方法,就可以進行各種圖案的繪圖,或是直接擴充海龜繪圖的方法,例如若要在目前的位置上繪製出一個正三角型,由海龜游動的方式, 可以如下繪製圖形:

如果要繪製實心的三角形,在撰寫方法時,在海龜游動的同時,記下三個頂點的座標,再呼叫API所提供的繪製實心多邊形方法即可。
如果要繪製點,可以如下結合兩個基本的海龜繪圖方法:

依照以下的描述,您可以自由撰寫並擴充您的海龜繪圖法,使繪圖的功能更加豐富,下面這個Java程式改寫自 Java 於演算法與資料結構之應用,在這邊僅提供程式碼作為參考,解說部份請徑自參考原書:
package onlyfun.caterpillar.graphics; // ---------------------------------- -- // * Turtle Graphics * // ------------------------------------ import java.awt.*; public class Turtle { public double Angle, // current angle LPX,LPY; // current position private double WX1,WY1,WX2,WY2, // canvas coordination VX1,VY1,VX2,VY2, // viewable area FACTX,FACTY; // scale private Graphics g; public Turtle() { Angle=0; LPX=LPY=0; } public void setGraphics(Graphics g) { this.g = g; } public Graphics getGraphics() { return g; } public void view(int x1,int y1,int x2,int y2) { g.setClip(x1,y1,x2-x1,y2-y1); VX1=(double)x1;VY1=(double)y1; VX2=(double)x2;VY2=(double)y2; FACTX=(VX2-VX1)/(WX2-WX1); FACTY=(VY2-VY1)/(WY2-WY1); } public void window(double x1,double y1,double x2,double y2) { WX1=x1;WY1=y1;WX2=x2;WY2=y2; FACTX=(VX2-VX1)/(WX2-WX1); FACTY=(VY2-VY1)/(WY2-WY1); } public void warp(double l) { LPX=LPX+l*Math.cos(Math.toRadians(Angle)); LPY=LPY+l*Math.sin(Math.toRadians(Angle)); } public void move(double l) { double x,y,x1,y1,x2,y2; x=LPX+l*Math.cos(Math.toRadians(Angle)); y=LPY+l*Math.sin(Math.toRadians(Angle)); x1=(LPX-WX1)*FACTX+VX1; y1=(WY2-LPY)*FACTY+VY1; x2=(x-WX1)*FACTX+VX1; y2=(WY2-y)*FACTY+VY1; g.drawLine((int)x1,(int)y1,(int)x2,(int)y2); LPX=x;LPY=y; } public void moveto(double x,double y) { double x1,y1,x2,y2; x1=(LPX-WX1)*FACTX+VX1; y1=(WY2-LPY)*FACTY+VY1; x2=(x-WX1)*FACTX+VX1; y2=(WY2-y)*FACTY+VY1; g.drawLine((int)x1,(int)y1,(int)x2,(int)y2); LPX=x;LPY=y; } public void setpoint(double x,double y) { LPX=x;LPY=y; } public void pset(double x,double y) { setpoint(x,y); moveto(x,y); } public void line(double x1,double y1,double x2,double y2) { setpoint(x1,y1); moveto(x2,y2); } public void turn(double a) { Angle=Angle+a; Angle=Angle-(int)Angle+((int)Angle % 360); } public void setangle(double a) { Angle=a; } }
|