twodimturtle.htm
来自「电脑图学(Computer Graphics)是资料结构、演算法与数学的应用」· HTM 代码 · 共 264 行
HTM
264 行
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="css/stdlayout.css" type="text/css">
<link rel="stylesheet" href="css/print.css" type="text/css">
<meta content="text/html; charset=gb2312" http-equiv="content-type">
<title>二维海龟绘图法</title>
</head>
<body>
<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>
<h1><a href="ComputerGraphics.htm">Computer Graphics: 二维海龟绘图法</a></h1>
海龟绘图法取名海龟并不是因为它的速度像乌龟,而是它绘图的方式就像海龟前进的方式。<br>
<br>
考虑海龟只能前进的情况(我也不知道海龟能不能倒着游?),在2D的情况下,也就是海龟只在一个XY平面运动的情况下,海龟的运动基本上只有前进与转弯两个动作,由此开始联想,定出海龟绘图法的几个基本方法: <br>
<br>
<ul>
<li>设定海龟起始位置</li>
</ul>
<div style="margin-left: 40px;">也就是将海龟直接放至某个(x, y)座标,而不进行任何的绘制动作。 <br>
<img style="width: 185px; height: 79px;" alt="" src="images/twoDimTurtle-1.jpg"><br>
</div>
<span class="postbody"></span><br>
<br>
<ul>
<li>海龟由目前位置游至指定座标</li>
</ul>
<div style="margin-left: 40px;">由目前位置游至(x, y)位置,并在经过的路径画上直线。 <br>
<img style="width: 183px; height: 81px;" alt="" src="images/twoDimTurtle-2.jpg"><br>
</div>
<br>
<br>
<ul>
<li>海龟由目前位置游动L长度</li>
</ul>
<div style="margin-left: 40px;">无论海龟目前的头朝向哪一个角度,由目前位置与角度游动L长度,并在经过的路径上画上直线。<br>
<img style="width: 184px; height: 82px;" alt="" src="images/twoDimTurtle-3.jpg"><br>
</div>
<br>
<br>
<ul>
<li>设定海龟目前头朝向的角度</li>
</ul>
<div style="margin-left: 40px;">角度的计算是以正X轴及头所成的角度来计算。 <br>
<img style="width: 181px; height: 102px;" alt="" src="images/twoDimTurtle-4.jpg"><br>
</div>
<br>
<br>
<ul>
<li>旋转海龟的头为指定的角度θ</li>
</ul>
<div style="margin-left: 40px;">即目前已成的角度 a 再加上θ,也就是与正X轴最后会成a+θ。 <br>
<img style="width: 183px; height: 113px;" alt="" src="images/twoDimTurtle-5.jpg"><br>
</div>
<br>
<br>
有了以上几个基本方法,就可以进行各种图案的绘图,或是直接扩充海龟绘图的方法,例如若要在目前的位置上绘制出一个正三角型,由海龟游动的方式, 可以如下绘制图形: <br>
<img style="width: 320px; height: 259px;" alt="" src="images/twoDimTurtle-6.jpg"><br>
<br>
如果要绘制实心的三角形,在撰写方法时,在海龟游动的同时,记下三个顶点的座标,再呼叫API所提供的绘制实心多边形方法即可。<br>
<br>
如果要绘制点,可以如下结合两个基本的海龟绘图方法: <br>
<img style="width: 182px; height: 81px;" alt="" src="images/twoDimTurtle-7.jpg"><br>
<br>
依照以下的描述,您可以自由撰写并扩充您的海龟绘图法,使绘图的功能更加丰富,下面这个Java程式改写自 <a href="http://www.drmaster.com.tw/info.asp?no=PG20098">Java 于演算法与资料结构之应用</a>,在这边仅提供程式码作为参考,解说部份请径自参考原书: <br>
<ul>
<li> Turtle.java
</li>
</ul>
<pre>package onlyfun.caterpillar.graphics;<br> <br>// ---------------------------------- -- <br>// * Turtle Graphics * <br>// ------------------------------------ <br> <br>import java.awt.*; <br> <br>public class Turtle { <br> public double Angle, // current angle <br> LPX,LPY; // current position<br> private double WX1,WY1,WX2,WY2, // canvas coordination <br> VX1,VY1,VX2,VY2, // viewable area <br> FACTX,FACTY; // scale <br> private Graphics g; <br> <br> public Turtle() { <br> Angle=0; <br> LPX=LPY=0; <br> } <br> <br> public void setGraphics(Graphics g) {<br> this.g = g;<br> }<br> <br> public Graphics getGraphics() {<br> return g;<br> }<br> <br> public void view(int x1,int y1,int x2,int y2) { <br> g.setClip(x1,y1,x2-x1,y2-y1); <br> VX1=(double)x1;VY1=(double)y1; <br> VX2=(double)x2;VY2=(double)y2; <br> FACTX=(VX2-VX1)/(WX2-WX1); <br> FACTY=(VY2-VY1)/(WY2-WY1); <br> } <br> <br> public void window(double x1,double y1,double x2,double y2) { <br> WX1=x1;WY1=y1;WX2=x2;WY2=y2; <br> FACTX=(VX2-VX1)/(WX2-WX1); <br> FACTY=(VY2-VY1)/(WY2-WY1); <br> } <br> <br> public void warp(double l) { <br> LPX=LPX+l*Math.cos(Math.toRadians(Angle)); <br> LPY=LPY+l*Math.sin(Math.toRadians(Angle)); <br> } <br> <br> public void move(double l) { <br> double x,y,x1,y1,x2,y2; <br> x=LPX+l*Math.cos(Math.toRadians(Angle)); <br> y=LPY+l*Math.sin(Math.toRadians(Angle)); <br> x1=(LPX-WX1)*FACTX+VX1; <br> y1=(WY2-LPY)*FACTY+VY1; <br> x2=(x-WX1)*FACTX+VX1; <br> y2=(WY2-y)*FACTY+VY1; <br> g.drawLine((int)x1,(int)y1,(int)x2,(int)y2); <br> LPX=x;LPY=y; <br> } <br> <br> public void moveto(double x,double y) { <br> double x1,y1,x2,y2; <br> x1=(LPX-WX1)*FACTX+VX1; <br> y1=(WY2-LPY)*FACTY+VY1; <br> x2=(x-WX1)*FACTX+VX1; <br> y2=(WY2-y)*FACTY+VY1; <br> g.drawLine((int)x1,(int)y1,(int)x2,(int)y2); <br> LPX=x;LPY=y; <br> } <br> <br> public void setpoint(double x,double y) { <br> LPX=x;LPY=y; <br> } <br> <br> public void pset(double x,double y) { <br> setpoint(x,y); <br> moveto(x,y); <br> } <br> <br> public void line(double x1,double y1,double x2,double y2) { <br> setpoint(x1,y1); <br> moveto(x2,y2); <br> } <br> <br> public void turn(double a) { <br> Angle=Angle+a; <br> Angle=Angle-(int)Angle+((int)Angle % 360); <br> } <br> <br> public void setangle(double a) { <br> Angle=a; <br> } <br>}</pre>
<br>
<br>
<br>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?