【計算機圖形學】用python的turtle進行簡單的圖形繪製
【計算機圖形學】用python的turtle進行簡單的圖形繪製
python的turtle模組
Turtle graphics is a popular way for introducing programming to kids.
It was part of the original Logo programming language developed by Wally Feurzig and Seymour Papert in 1966.
Imagine a robotic turtle starting at (0, 0) in the x-y plane. After an import turtle, give it the command turtle.forward(15), and it moves (on-screen!) 15 pixels in the direction it is facing, drawing a line as it moves. Give it the command turtle.right(25), and it rotates in-place 25 degrees clockwise.
By combining together these and similar commands, intricate shapes and pictures can easily be drawn.
以上一段是我在使用VS Code時,看到的對turtle模組的介紹。大致翻譯一下:
海龜(Turtle)製圖是向孩子介紹程式設計的一個流行方式。
它是Wally Feurzig和Seymour Papert在1966年創造的原始Logo程式語言的一部分。
想象一下,一個自動的海龜從xy平面的原點(0,0)開始,在輸入turtle模組後
import turtle
給出一行命令
turtle.forward(15)
然後海龜就在螢幕上向它面向的方向前進了15個畫素點,並且在行進道路上劃出了一條線。給它一個命令
turtle.right(25)
它就在原地順時針旋轉了25度。
通過結合這些命令和其他相似的命令,就能夠輕易地畫出複雜的幾何圖形和圖片。
可以看出,python的turtle模組是一個功能非常強大,並且操作簡單的繪圖工具。
廢話不多說,turtle有很多的庫函式,網上很容易就查得到,我這裡就不多介紹了(或許以後會單寫一篇文章進行詳細的介紹),接下來直接進入正題!
繪製圖形
在turtle中有直接繪製線、矩形、圓形、橢圓形等的函式,但計算機圖形學(至少我們的課程)要求用繪製畫素點的方式繪製線、圖形,而自帶的繪點函式只能在turtle所在位置繪點。
繪製點
下面給出在某個畫素點繪製點的函式。
import turtle as pen //下面程式碼均預設以pen代替turtle欄位 def DrawPixel(x,y) : pen.up() //因為turtle在執行goto()時, //會在路徑上畫出一條直線, //所以先把筆擡起來 pen.goto(x,y) //turtle到指定座標畫素點 pen.dot(2) //繪製直徑為2的畫素點 //實測引數為1時在我的電腦上看不到點,所以用2
其中x,y是畫素點座標。turtle模組在繪圖時,會預設在畫布正中央為座標原點(0,0)。
繪製直線
def DrawLine(x1,y1,x2,y2) :
print ("called")
dx = abs(x2 - x1)
sx = 1 if(x1<x2) else -1
dy = abs(y2 - y1)
sy = 1 if(y1<y2) else -1
err = dx if(dx>dy) else -dy
l = dx if(dx>dy) else dy
for i in range(0,l) :
DrawPixel(x1,y1)
if x1 == x2 and y1 == y2 :
break
e2 = err
if e2 >= -dx :
err = err - dy
x1 = x1 + sx
if e2 <= dy :
err = err + dx
y1 = y1 + sy
繪製橢圓
首先,橢圓是一箇中心對稱、雙軸對稱圖形,所以只需要繪製出1/4的圖形,其餘部分都可根據對稱畫出。
給出長短半徑,進行繪製。
def PaintEllipse(a,b) :
pen.delay(0.1) //delay是turtle函式與函式之間執行的間隔,
//括號中為時間間隔,單位毫秒
//因為繪點需要一個點一個點繪製
//而不是靠turtle的移動
//否則使用pen.speed()
//修改turtle的移動速度
x = 0
y = b
d1 = b*b + a*a *(0.25 - b)
DrawPixel(x,y)
DrawPixel(-x,-y)
while b*b*(x+1) < a*a*(y-0.5) :
if d1 < 0 :
d1 = d1 + b * b * (2 * x + 3)
x = x + 1
else :
d1 = d1 + b*b*(2*x+3)+a*a*(2-2*y)
x = x + 1
y = y - 1
DrawPixel(x,y)
DrawPixel(-x,y)
DrawPixel(-x,-y)
DrawPixel(x,-y)
d2 = math.sqrt(b*(x+0.5)) + math.sqrt(a*(y-1)) - math.sqrt(a*b)
while y > 0 :
if d2 < 0 :
d2 = d2 + b*b*(2*x+2) + a*a*(-2*y+3)
x = x + 1
y = y - 1
else :
d2 = d2 + a*a*(-2*y+3)
y = y - 1
DrawPixel(x,y)
DrawPixel(-x,y)
DrawPixel(-x,-y)
DrawPixel(x,-y)
呼叫函式
PaintEllipse(100,50) //(橫軸半徑,豎軸半徑)
結果如下
繪製六邊形
給出六點座標,進行繪製並填充。
x,y為六點的list,順序需對應
def PaintSixEdge(x,y) :
i = 0
pen.begin_fill()
while i < 5 :
DrawLine(x[i],y[i],x[i+1],y[i+1])
i = i + 1
print (x[i])
DrawLine(x[5],y[5],x[0],y[0])
pen.end_fill()
呼叫函式
x = [100,200,100,-100,-200,-100]
y = [100,0,-100,-100,0,100]
PaintSixEdge(x,y)
結果如下:
繪製n次貝塞爾曲線
x,y為點的list,順序需對應
def PaintBezier(x,y) :
pen.color("red")
number = len(x)
t = 0.0
while t < 1 :
for k in range(1,number+1) :
for i in range(0,number-k) :
x0 = xpos(x,i,k,t)
y0 = ypos(y,i,k,t)
DrawPixel(x0,y0)
t = t + 0.001
def xpos(x,i,k,t) :
if k == 0 :
return x[i]
else :
return (1-t)*xpos(x,i,k-1,t) + t*xpos(x,i+1,k-1,t)
def ypos(y,i,k,t) :
if k == 0 :
return y[i]
else :
return (1-t)*ypos(y,i,k-1,t) + t*ypos(y,i+1,k-1,t)
呼叫函式
x = [100,200,100,-100,-200,-100]
y = [100,0,-100,-100,0,100]
PaintBezier(x,y)
結果如下:
結語
通過複雜的迴圈,以及改變畫筆顏色,還能夠生成各種各樣的好看的圖形,感興趣的小夥伴們自己試試吧!