Turtle 绘制蟒蛇
问题分析
用程序绘制一条蟒蛇
计算机绘图
- 计算机绘图是什么原理?
- 一段程序为何能够产生窗体?
- 为何能在窗体上绘制图形?
- Python蟒蛇绘制从哪里开始呢?
- 如何绘制一条线?
- 如何绘制一个弧形?
- 如何绘制一个蟒蛇?
输入输出
- 输入:开始画蟒蛇的指令
- 处理:创建画布,在画布上画画
- 输出:在窗体上呈现一条蟒蛇
算法设计
根据上面蟒蛇的图案:
- 创建一个画布
- 逆时针从左往右画半圆
- 顺时针从左往右画半圆
- 逆时针从左往右画半圆
- 顺时针从左往右画半圆
- 逆时针从左往右画半圆
- 顺时针从左往右画半圆
- 逆时针从左往右画半圆
- 顺时针从左往右画半圆
- 从左往右画一条横线
- 逆时针从下往上画半圆
- 从右往左画一条横线
- 结束
实例编写
初步实现
import turtle
turtle.setup(1000, 800, 200, 200)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80/2)
turtle.forward(40)
turtle.circle(16, 180)
turtle.forward(40 * 2/3)
turtle.done()
运行结果:
很明显,上面的绘制图形跟预想的图形有一定的差别,但外形上大体还是符合要求的。
改进算法
DrawPython1.py
import turtle
turtle.setup(1000, 800, 200, 200) turtle.setheading(-40) turtle.pensize(25) turtle.circle(40, 80) turtle.circle(-40, 80) turtle.circle(40, 80) turtle.circle(-40, 80) turtle.circle(40, 80) turtle.circle(-40, 80) turtle.circle(40, 80) turtle.circle(-40, 80) turtle.circle(40, 80/2) turtle.fd(40) turtle.circle(16, 180) turtle.fd(40 * 2/3) turtle.done()
运行结果:<br /><br />已经非常接近预想中的结果了,但还是有些小问题,比如没有颜色,超出画布的边界了。
<a name="ntnAg"></a>
### 进一步改进
1. 调整画笔的起始位置,让蟒蛇居中显示
1. 给画笔上色,来一条有颜色的蟒蛇
```python
#!/usr/bin/env python
# encoding: utf-8
#DrawPython1.py
import turtle
turtle.setup(1000, 800, 200, 200)
turtle.penup()
turtle.forward(-250)
turtle.pendown()
turtle.setheading(-40)
turtle.pensize(25)
turtle.pencolor("purple")
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.pencolor("red")
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80/2)
turtle.fd(40)
turtle.circle(16, 180)
turtle.fd(40 * 2/3)
turtle.done()
运行结果:
至此,我们已经可以画出预想中的蟒蛇了,颜色大小都符合需求。在不修改主体逻辑,不影响运行结果的情况,可以进一步的精简代码。代码越少出错的机会也越少。
完善代码
- 采用循环的机制绘制蟒蛇的身体
- 为什么要采用循环机制呢?
- 假如我们需要画一条很长很长的蟒蛇….
- 简单重复的事情交给计算机来做
- 每一个计算问题都是简单又可以重复的事情
- 一个大的计算问题可以拆分为若干个小的计算问题
import turtle
turtle.setup(650, 350, 200, 200)
turtle.penup()
turtle.forward(-250)
turtle.pendown()
turtle.pensize(25)
turtle.pencolor("purple")
turtle.setheading(-40)
for i in range(4):
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80/2)
turtle.forward(40)
turtle.circle(16, 180)
turtle.forward(40 * 2/3)
turtle.done()
运行效果
举一反三
- 蟒蛇的颜色:黑色、白色、七彩色…
- 蟒蛇的长度:1节、3节、10节…
- 蟒蛇的方向:向左走、斜着走…
- 蟒蛇的数量:7条蟒蛇…
七彩蟒蛇
range() 函数
import turtle
turtle.setup(1080, 350, 200, 200)
turtle.penup()
turtle.forward(-400)
turtle.pendown()
turtle.pensize(25)
turtle.setheading(-40)
colors = ['red', 'yellow', 'orange', 'purple', 'brown', 'navy', 'olive']
for i in range(7):
print(i)
color = colors[i]
turtle.pencolor(color)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80/2)
turtle.forward(40)
turtle.circle(16, 180)
turtle.forward(40 * 2/3)
turtle.done()
import turtle
turtle.setup(1080, 350, 200, 200)
turtle.penup()
turtle.forward(-400)
turtle.pendown()
turtle.pensize(25)
turtle.setheading(-40)
colors = ['red', 'yellow', 'orange', 'purple', 'brown', 'navy', 'olive']
nums = [0, 1, 2, 3, 4, 5, 6, 7]
for i in nums:
color = colors[i]
turtle.pencolor(color)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80/2)
turtle.forward(40)
turtle.circle(16, 180)
turtle.forward(40 * 2/3)
turtle.done()
颜色数组
import turtle
turtle.setup(1080, 350, 200, 200)
turtle.penup()
turtle.forward(-400)
turtle.pendown()
turtle.pensize(25)
turtle.setheading(-40)
colors = ['red', 'yellow', 'orange', 'purple', 'brown', 'navy', 'olive']
for color in colors:
print(color)
turtle.pencolor(color)
turtle.circle(40, 80)
turtle.circle(-40, 80)
turtle.circle(40, 80/2)
turtle.forward(40)
turtle.circle(16, 180)
turtle.forward(40 * 2/3)
turtle.done()
进一步拓展
- Python蟒蛇绘制问题是各类图像绘制问题的代表
- 圆形绘制、五角星绘制、国旗绘制、机器猫绘制…
- 掌握绘制一条线的方法,就可以绘制整个世界
绘图案例
小猪佩奇
#!/usr/bin/env python
# encoding: utf-8
import turtle as t
def nose(x,y):#鼻子
t.pu()
t.goto(x,y)
t.pd()
t.seth(-30) # 笔的角度为-30°
t.begin_fill()
a = 0.4
for i in range(120):
if 0<=i<30 or 60<=i<90:
a=a+0.08
t.lt(3) #向左转3度
t.fd(a) #向前走a的步长
else:
a=a-0.08
t.lt(3)
t.fd(a)
pass
t.end_fill() # 依据轮廓填充
t.pu()
t.seth(90) # 笔的角度为90度
t.fd(25) # 向前移动25
t.seth(0) # 转换画笔的角度为0
t.fd(10)
t.pd()
t.pencolor(255,155,192) # 设置画笔颜色
t.seth(10)
t.begin_fill()
t.circle(5) # 画一个半径为5的圆
t.color(160,82,45) # 设置画笔和填充颜色
t.end_fill()
t.pu()
t.seth(0)
t.fd(20)
t.pd()
t.pencolor(255,155,192)
t.seth(10)
t.begin_fill()
t.circle(5)
t.color(160,82,45)
t.end_fill()
pass
def head(x,y): #头
t.color((255,155,192),"pink")
t.pu()
t.goto(x,y)
t.seth(0)
t.pd()
t.begin_fill()
t.seth(180)
t.circle(300,-30) # 顺时针画一个半径为300,圆心角为30°的园
t.circle(100,-60)
t.circle(80,-100)
t.circle(150,-20)
t.circle(60,-95)
t.seth(161)
t.circle(-300,15)
t.pu()
t.goto(-100,100)
t.pd()
t.seth(-30)
a=0.4
for i in range(60):
if 0<=i<30 or 60<=i<90:
a=a+0.08
t.lt(3) #向左转3度
t.fd(a) #向前走a的步长
else:
a=a-0.08
t.lt(3)
t.fd(a)
t.end_fill()
pass
pass
def ears(x,y): #耳朵
t.color((255,155,192),"pink")
t.pu()
t.goto(x,y)
t.pd()
t.begin_fill()
t.seth(100)
t.circle(-50,50)
t.circle(-10,120)
t.circle(-50,54)
t.end_fill()
t.pu()
t.seth(90)
t.fd(-12)
t.seth(0)
t.fd(30)
t.pd()
t.begin_fill()
t.seth(100)
t.circle(-50,50)
t.circle(-10,120)
t.circle(-50,56)
t.end_fill()
pass
def eyes(x,y): #眼睛
t.color((255,155,192),"white")
t.pu()
t.seth(90)
t.fd(-20)
t.seth(0)
t.fd(-95)
t.pd()
t.begin_fill()
t.circle(15)
t.end_fill()
t.color("black")
t.pu()
t.seth(90)
t.fd(12)
t.seth(0)
t.fd(-3)
t.pd()
t.begin_fill()
t.circle(3)
t.end_fill()
t.color((255,155,192),"white")
t.pu()
t.seth(90)
t.fd(-25)
t.seth(0)
t.fd(40)
t.pd()
t.begin_fill()
t.circle(15)
t.end_fill()
t.color("black")
t.pu()
t.seth(90)
t.fd(12)
t.seth(0)
t.fd(-3)
t.pd()
t.begin_fill()
t.circle(3)
t.end_fill()
pass
def cheek(x,y): #腮
t.color((255,155,192))
t.pu()
t.goto(x,y)
t.pd()
t.seth(0)
t.begin_fill()
t.circle(30)
t.end_fill()
pass
def mouth(x,y): #嘴
t.color(239,69,19)
t.pu()
t.goto(x,y)
t. pd()
t.seth(-80)
t.circle(30,40)
t.circle(40,80)
pass
def body(x,y): #身体
t.color("red",(255,99,71))
t.pu()
t.goto(x,y)
t.pd()
t.begin_fill()
t.seth(-130)
t.circle(100,10)
t.circle(300,30)
t.seth(0)
t.fd(230)
t.seth(90)
t.circle(300,30)
t.circle(100,3)
t.color((255,155,192),(255,100,100))
t.seth(-135)
t.circle(-80,63)
t.circle(-150,24)
t.end_fill()
pass
def hands(x,y): #手
t.color((255,155,192))
t.pu()
t.goto(x,y)
t.pd()
t.seth(-160)
t.circle(300,15)
t.pu()
t.seth(90)
t.fd(15)
t.seth(0)
t.fd(0)
t.pd()
t.seth(-10)
t.circle(-20,90)
t.pu()
t.seth(90)
t.fd(30)
t.seth(0)
t.fd(237)
t.pd()
t.seth(-20)
t.circle(-300,15)
t.pu()
t.seth(90)
t.fd(20)
t.seth(0)
t.fd(0)
t.pd()
t.seth(-170)
t.circle(20,90)
pass
def foot(x,y): #脚
t.pensize(10)
t.color((240,128,128))
t.pu()
t.goto(x,y)
t.pd()
t.seth(-90)
t.fd(40)
t.seth(-180)
t.color("black")
t.pensize(15)
t.fd(20)
t.pensize(10)
t.color((240,128,128))
t.pu()
t.seth(90)
t.fd(40)
t.seth(0)
t.fd(90)
t.pd()
t.seth(-90)
t.fd(40)
t.seth(-180)
t.color("black")
t.pensize(15)
t.fd(20)
pass
def tail(x,y): #尾巴
t.pensize(4)
t.color((255,155,192))
t.pu()
t.goto(x,y)
t.pd()
t.seth(0)
t.circle(70,20)
t.circle(10,330)
t.circle(70,30)
def setting(): #参数设置
t.pensize(4) # 设置画笔的大小
t.hideturtle()
t.colormode(255) # 设置GBK颜色范围为0-255
t.color((255,155,192),"pink") # 设置画笔颜色和填充颜色(pink)
t.setup(840,500) # 设置主窗口的大小为840*500
t.speed(100) # 设置画笔速度
pass
if __name__ == '__main__':
setting() #画布、画笔设置
nose(-100,100) #鼻子
head(-69,167) #头
ears(0,160) #耳朵
eyes(0,140) #眼睛
cheek(80,10) #腮
mouth(-20,30) #嘴
body(-32,-8) #身体
hands(-56,-45) #手
foot(2,-177) #脚
tail(148,-155) #尾巴
t.done() #结束
太阳花
import turtle as t
import time
t.color("red", "yellow")
t.speed(10)
t.begin_fill()
for _ in range(50):
t.forward(200)
t.left(170)
t.end_fill()
t.hideturtle()
t.done()
树1
from turtle import *
from random import *
from math import *
def tree(n, l):
pd()
t = cos(radians(heading() + 45)) / 18 + 0.25
pencolor(t, t, t)
pensize(n / 4)
forward(l)
if n > 0:
b = random() * 15 + 10
c = random() * 15 + 10
d = l *(random() * 0.35 + 0.6)
right(b)
tree(n - 1, d)
left(b + c)
tree(n - 1, d)
right(c)
else:
right(90)
n = cos(radians(heading() - 45)) / 4 + 0.5
pencolor(n, n, n)
circle(2)
left(90)
pu()
backward(l)
pass
def drawTree():
bgcolor(0.5, 0.5, 0.5)
ht()
speed(10)
tracer(1000, 0)
left(90)
pu()
backward(300)
tree(13, 100)
done()
pass
if __name__ == "__main__":
drawTree()
树2
import random
from turtle import *
from time import sleep
t = Turtle()
w = Screen()
def tree(branchLen, t):
if branchLen > 3:
if 8 <= branchLen <= 12:
if random.randint(0, 2) == 0:
t.color('snow')
else:
t.color('lightcoral')
t.pensize(branchLen / 3)
elif branchLen < 8:
if random.randint(0, 1) == 0:
t.color('snow')
else:
t.color('lightcoral')
t.pensize(branchLen / 2)
else:
t.color('sienna')
t.pensize(branchLen / 10)
t.forward(branchLen)
a = 1.5 * random.random()
t.right(20*a)
b = 1.5 * random.random()
tree(branchLen-10*b, t)
t.left(40*a)
tree(branchLen-10*b, t)
t.right(20*a)
t.up()
t.backward(branchLen)
t.down()
pass
def petal(m, t): # 树下花瓣
for i in range(m):
a = 200 - 400 * random.random()
b = 10 - 20 * random.random()
t.up()
t.forward(b)
t.left(90)
t.forward(a)
t.down()
t.color("lightcoral")
t.circle(1)
t.up()
t.backward(a)
t.right(90)
t.backward(b)
pass
def main():
hideturtle()
getscreen().tracer(15, 0)
screensize(bg='wheat')
t.left(90)
t.up()
t.backward(150)
t.down()
t.color('sienna')
tree(60, t)
petal(100, t)
done()
pass
if __name__ == "__main__":
main()
时钟
所有的课程结束后,学员可以自己独立编写出下面的闹钟。