今天我们接着铸造美国队长的盾牌。
前面我们已经把四个同心圆画好了(美国队长的盾(一) 同心圆),就缺“画龙点睛”之笔的五角星了。那么今天我们就来纯手工打造这样一个五角星。
初中老师课堂又开始了。要画这样一个五角星,有些长度和角度还是需要计算一下的。
比如说五角星的顶角为36°,画完一条边需要旋转的角度等等。具体的计算方法可以参考上面这张纯手工打造的示意图。看上去还真有一点按照工程图纸来铸造的意思。
我不知道大家是怎么来画五角星的,我的习惯是画五条边,每次旋转36°。就是下面这个示意图。
后面填充颜色的时候发现一个问题,为什么中间有五条线,跟想象的不一样。我以为天真的以为,填充色为白色,中间的线就会被掩盖掉。但是现实狠狠的扇了我一记响亮的耳光。
既然不能偷懒,那就老老实实一笔一笔来画了。那就画五个等腰三角形来构成这个五角星。酱紫的~
那么问题来了,等腰三角形的变长是多少。假设外接圆的半径是r,那么红色线段的长度应该为r*cos54。那么蓝色线段,也就是等腰三角形的边长应该为r*cos54/cos36。
下面我们就来看看效果,这次对了吧!
最后一步,合并起来。这款美队盾牌就完工了。
import turtle
import math
# 定义一个画多线段的函数,这个函数有五个参数
# t是turtle对象,n是线段数,length为每条线段的长度
# angle每次旋转的角度,direction旋转的方向
def polyline(t, n, length, angle, direction):
# 循环n次画出n条线段
for i in range(n):
# 画边
t.fd(length)
# 判断旋转的方向
if direction == "left":
t.lt(angle)
elif direction == "right":
t.rt(angle)
# 画弧线的函数,t是turtle对象,r是弧的半径
# angle是每次旋转的角度,direction是弧旋转的方向
def arc(t, r, angle, direction):
# 根据半径计算圆的周长
circumference = 2 * math.pi * r
# 根据弧度计算弧长
arc_len = angle / 360 * circumference
# 这里设定线段长度为3,计算线段数,int强制转换成整数
n = int(arc_len / 3) + 1
# 得到整数的线段数之后,重新计算线段的长度,
# 得到的length这时可能是小数了
length = arc_len / n
# 计算每一次旋转的角度
step_angle = angle / n
# 调用前面定义的画多线段的函数来画弧线
polyline(t, n, length, step_angle, direction)
# 移动的函数,t是turtle对象, direction是移动的方向
# distance是移动的距离
def move(t, direction, distance):
# 提笔,再移动不会在画布上留下痕迹
t.pu()
# 判断移动方向,fd向前,bk向后,移动相应距离
if direction == "fd":
t.fd(distance)
elif direction == "bk":
t.bk(distance)
# 放下笔,再移动会在画布上留下痕迹
t.pd()
# 让箭头回到原点
def home(t):
t.pu()
t.home()
t.pd()
# 定义一个画圆的函数,这个函数有三个参数
# t是turtle对象,r圆的半径,color圆的填充色
def circle(t, r, color):
# 回到原点
home(t)
# 移动一个半径的距离
move(t, 'fd', r)
# 调整箭头正北
t.setheading(90)
# 设置填充色
t.begin_fill()
t.fillcolor(color)
# 画圆
arc(t, r, 360, 'left')
# 填充结束
t.end_fill()
# 画五角星的函数,t是turtle对象
# r外接圆的半径,color是填充的颜色
def star(t, r, color):
home(t)
t.setheading(90)
move(t, 'fd', r)
t.rt(180 - 18)
# 计算五个等腰三角形的边长
edge = math.cos(54 / 360 * 2 * math.pi) * r / math.cos(36 / 360 * 2 * math.pi)
t.begin_fill()
t.fillcolor(color)
# 画五个角
for i in range(5):
t.fd(edge)
t.lt(72)
t.fd(edge)
t.rt(180 - 36)
t.end_fill()
# 定义一个画盾牌的函数
# t是turtle对象,r是最大圆的半斤
def shield(t, r):
# 计算一个合适的步长
step = r / 150 * 30
# 画第一个圆
circle(bob, r, 'red')
# 画第二个圆
circle(bob, r - step, 'white')
# 画第三个圆
circle(bob, r - 2 * step, 'red')
# 画第四个圆
circle(bob, r - 3 * step, 'blue')
# 画五角星
star(bob, r - 3 * step, 'white')
bob = turtle.Turtle()
shield(bob, 100)
bob.hideturtle()
turtle.mainloop()
来看看完整的过程