学python第十节:海龟绘图体系

让小海龟画出五彩斑斓的世界。

今天学一个简单的绘图工具,叫做海龟绘图(Turtle Graphics)。

先欣赏一个绘制蟒蛇的代码:

PythonDraw.py                    注释
import turtle                    调用海龟绘图函数turtle
turtle.setup(650, 350, 200, 200)  定义绘图窗体
turtle.penup()                   画笔抬起
turtle.fd(-250)                  向后(X轴负方向)移动250个像素
turtle.pendown()                 画笔落下,开始绘画
turtle.pensize(25)               设置画笔粗细,款25像素
turtle.pencolor("purple")          设置画笔颜色为紫色
turtle.seth(-40)                设置画笔朝向角度为-40°
for i in range(4):              使用for in 遍历循环,循环四次结束
    turtle.circle(40, 80)      画笔画弧线,画圆心在左侧,半径为40像素,角度为80°的弧线
    turtle.circle(-40, 80)     画笔画弧线,画圆心在右侧,半径为40像素,角度为80°的弧线
turtle.circle(40, 80/2)        画笔画弧线,画圆心在左侧,半径为40像素,角度为40°的弧线
turtle.fd(40)                  向前画40像素的直线
turtle.circle(16, 180)         画笔画弧线,画圆心在左侧,半径为16像素,角度为1800°的弧线
turtle.fd(40 * 2/3)            画笔向前画80/3像素的直线
turtle.done()                  绘制结束并保持当前绘制结果,若没有则窗口迅速关闭
执行一次turtle.circle(40, 80) turtle.circle(-40, 80),需要四次

turtle库基本概览: turtle库是python的标准库(python计算生态=标准库+第三方库),使用时直接调用(import turtle)即可。

标准库:随解释器直接安装到操作系统的功能模块。

第三方库:需要进过安装才能使用的模块

Turtle的原理是什么呢?使用海龟作图,我们不仅能够只用几行代码就创建出令人印象深刻的视觉效果,而且还可以跟随海龟看看每行代码如何影响到它的移动。这能够帮助我们理解代码的逻辑。

Turtle绘画窗体如何布局呢:

Turtle的坐标是怎么规定的呢?

在海龟作图中,我们可以编写指令让一个虚拟的(想象中的)海龟在屏幕上来回移动。这个海龟带着一只钢笔,我们可以让海龟无论移动到哪都使用这只钢笔来绘制线条。通过编写代码,以各种很酷的模式移动海龟,我们可以绘制出令人惊奇的图片,对于海龟来说,有前进,后退,旋转等爬行行为,是靠自身角度方位来完成,刚开始,小海龟在画布正中央,坐标为(0,0),头部方向为向X轴正方向。

这里有个turtle的参数,turtle.goto(x,y),指的是小海龟到坐标(x,y)的地方。需要脑海里时刻有小海龟头的朝向,可以用一个例子说明:

Turtle的角度是怎么规定的呢?

海龟的向前向后走很好理解,最难的是在拐弯(走弧线)和走圆圈

1. 官方使用的绘制方法 circle

circle 方法是 Python 官方使用的方法。circle(r半径,angle度数)。起始位置在圆的切线方向,逆时针方向绘制。

例如,在绘制半径为 100 的圆形的时候。使用方法为

t.circle(100)

在绘制半圆的时候,实际是 360 度的圆的一半,使用方法为

t.circle(100, 180)

实际上在这个地方 circle 方法有第三个参数,官方文档解释说,圆实际是以其内切正多边形来近似表示的,其边的数量由 steps 指定(第三个参数)。我们在这里不需要管第三个参数。使用前两个即可。

2. 补充个发散思维,使用循环绘制圆

利用循环的思想,当我们绘制多边形的时候,边数足够多的话,就逼近于圆了。

我们尝试绘制下 360 边形

for i in range(0,360):
    t.fd(1)
    t.rt(360/360)

这个地方有两个问题,一是,绘制速度慢,二是无法确定圆的半径。

绘制速度慢是因为我们实际上循环了 360 次,所以速度慢,可以考虑用 36 边形进行处理。无法确定圆的半径可以通过计算来得到一个通解。

圆的周长是 2*Pi*r = 360*fd,fd = 2*Pi*r / 360 = 0.0174 * r,得到倍数是 0.0174,即在 fd 里填 0.0174*半径。

我们尝试绘制半径为 100 的圆形

for..in.. 就是把每个元素代入变量i,然后执行缩进块的语句遍历循环函数,从0到360循环执行

for i in range(0,360): 
    t.fd(0.0174*100)
    t.rt(360/360)

36 边形通过计算是 t.fd(0.174*半径)。

那么如何绘制半圆呢,实际上我们这个地方是通过循环的次数来控制圆的弧度。

使用方法为

for i in range(0,180):    
    t.fd(0.0174*100)
    t.rt(1)

四分之一圆的话循环 90 次就可以了。

3. 两种方法的比较

方法二是利用循环的思想逼近成圆。使用 for 循环绘制圆形,可以更好的理解逼近的思想以及熟悉循环的过程。虽然要记忆数字 0.0174 以及写更多的程序,但是也更好的理解了程序本身。同时,在方法二中,虽然使用 360 边形,速度会变慢,但是 360 和角度进行了结合,一圈是 360 度,旋转了 360 次。也方便进行计算。

我们现在只需要掌握第一种方法就可以了。

Turtle的颜色体系:

turtle.pencolor(); 没有参数传入,返回当前画笔颜色,传入参数设置画笔颜色,可以是字符串如”green”, red,也可以是RGB 3元组。

turtle.pencolor(blue)

turtle.pencolor(52,209,32)

常用的颜色参数如下:

Turtle常用参数汇总:

画笔的属性:turtle.pensize() 设置画笔的宽度turtle.pencolor(color) 没有参数传入,返回当前画笔颜色,color参数有三种形式传入参数,可以是字符串形式(颜色的英文,字母用小写),如”green”, red;也可以是RGB小数值或元组值(3元组)(每个小数或元组值对应的有颜色表,感兴趣可以自己了解一下,因为鄙人也不是特别清楚颜色这块)turtle.speed(speed) 设置画笔移动速度,画笔绘制的速度范围[0,10]整数,数字越大越快

画笔运动命令:turtle.forward(distance) 向当前画笔方向移动distance像素长度turtle.backward(distance) 向当前画笔相反方向移动distance像素长度turtle.right(degree) 顺时针移动degree°turtle.left(degree) 逆时针移动degree°turtle.pendown() 移动时绘制图形,缺省时也为绘制turtle.goto(x,y) 将画笔移动到坐标为x,y的位置turtle.penup() 提起笔移动,不绘制图形,用于另起一个地方绘制turtle.circle(radius,extent) 根据半径radius绘制extent角度的弧形,若无extent参数则画圆,radius为正(负),表示圆心在画笔的左边(右边)画圆,参数为正则是顺时针画圆,参数为负则是逆时针画圆turtle.setx( ) 将当前x轴移动到指定位置,y轴不变turtlr.sety( ) 将当前y轴移动到指定位置,x轴不变turtle.setheading(angle) 设置当前箭头朝向为angle角度,0-向右,90-向上,180-向左,270-向下turtle.home() 设置当前画笔位置为原点,朝向东。turtle.dot() 绘制一个指定直径和颜色的圆点turtle.setpos(x,y) 机器小乌龟定位到x=,y=turtle.pos() 获得当前位置turtle.xcor() 获得X坐标turtle.ycor() 获得Y坐标

画笔控制命令:turtle.fillcolor(colorstring) 绘制图形的填充颜色turtle.color(color1, color2) 同时设置pencolor=color1, fillcolor=color2turtle.filling() 返回当前是否在填充状态turtle.begin_fill() 准备开始填充图形turtle.end_fill() 填充完成turtle.hideturtle() 隐藏画笔的turtle形状turtle.showturtle() 显示画笔的turtle形状

全局控制命令:turtle.clear() 清空turtle窗口,但是turtle的位置和状态不会改变turtle.reset() 清空窗口,重置turtle状态为起始状态turtle.undo() 撤销上一个turtle动作turtle.isvisible() 返回当前turtle是否可见stamp() 复制当前图形turtle.write(s [,font=(font-name,font_size,font_type)])写文本,s为文本内容,font是字体的参数,分别为字体名称,大小和类型;font为可选项,font参数也是可选项

再来看看个好玩的例子

import turtle         使用turtle函数
turtle.speed(1)        绘制速度为1
turtle.pensize(4)      线条宽度为4像素

turtle.color(black, black)  
turtle.begin_fill()
右中圆
turtle.circle(50,180)
左大圆
turtle.circle(100,180)
左中圆
turtle.left(180)
turtle.circle(-50,180)
turtle.end_fill()

turtle.color(white, white)
turtle.begin_fill()
上小圆
turtle.left(90)
turtle.penup()
turtle.forward(35)
turtle.right(90)
turtle.pendown()
turtle.circle(15)
turtle.end_fill()

turtle.color(black, black)
turtle.begin_fill()
下小圆
turtle.left(90)
turtle.penup()
turtle.backward(70)
turtle.pendown()
turtle.left(90)
turtle.circle(15)
turtle.end_fill()

右大圆
turtle.right(90)
turtle.up()
turtle.backward(65)
turtle.right(90)
turtle.down()
turtle.circle(100, 180)

turtle.done()

event_note 10月 17, 2022

account_box 回国加速器

发表回复