上回咱们试着画了五星红旗的辅助线和辅助圆,这样帮助咱们理解了五角星的坐标。
这回咱们正式来画五星红旗,画五星红旗最难的地方在于算出来右侧4个小五角星的朝向。
咱们知道大五角星是朝向正上方的,也就是90度,而右侧的小五角星都是朝向左侧的大五角星的,如果是朝向正左侧,那就是180度,实际上显示不是刚好180度,上面的2个小五角星的朝向不足180度,下面的2个小五角星的朝向则不止是180度。
那么到底是多少度呢,此时咱们得用上三角函数了,这是高中知识,对于正在学习海龟画图的小学生来说,可以直接用成人算好的这个朝向角度即可。
_circles = [
{"x": -10, "y": 5, "r": 3, "h": 90.00},
{"x": -5, "y": 8, "r": 1, "h": 210.96},
{"x": -3, "y": 6, "r": 1, "h": 188.13},
{"x": -3, "y": 3, "r": 1, "h": 164.05},
{"x": -5, "y": 1, "r": 1, "h": 141.34}
]
上面的这个h就是heading,就是五角星的朝向。
那么对于有追求的大人来说,如果想用代码来算的吧,其实我们能够看出来第一个小五角星中心与大五角星的中心组成的直角三角形的两条边分别为3和5,可以算出这个锐角是arctan(3/5),拿手机上的计算器调出来科学计算器能够算出来。
如果用Python来算的吧,就是如下这样,第一次计算出来的是弧度,咱们得把弧度转化为角度。
import math
def get_angle_degree_by_2sides(side1,side2):
"""根据直角三角形的两条邻边计算角度"""
return math.degrees(math.atan(side1/side2))
这样就可以一个一个的都自己来算一下,非常精确的算一下。
大五角星的中心坐标是(x0,y0),小五角星的中心坐标是(x, y),那么直角三角形的两条边,边长分别为y-y0和x-x0。
def calc_headings():
x0, y0 = circles[0].get("x"), circles[0].get("y")
for i in range(1,len(circles)):
x, y=circles[i].get("x"), circles[i].get("y")
angle_degree=get_angle_degree_by_2sides(y-y0,x-x0)
print(f"angle degree {i}:{angle_degree}")
circles[i]["h"]=180 + angle_degree
print(circles)
其实我们知道了坐标和角度,到了最后一步的画星星,反倒成了最简单的了。
def draw_stars(self):
for circle in self._circles:
self.draw_star(circle["x"],circle["y"],circle["r"],circle["h"])
def draw_red_flag(self):
self.draw_flag()
self.draw_lines()
self.draw_circles()
self.draw_stars()
turtle.hideturtle()
turtle.done()

然后这时候咱们把计算和辅助线以及辅助圆的代码去掉,其实最终代码没有多少行的。
以下代码是精简版,速度也调慢了,方便大家看到效果,把单位也从默认的10改成了30,也就是画了一个900*600的五星红旗。
import turtle
class Draw5StarsFlag:
_unit=10
_star_side_len_ratio = 0.726542528
_circles = [
{"x": -10, "y": 5, "r": 3, "h": 90.00},
{"x": -5, "y": 8, "r": 1, "h": 210.96},
{"x": -3, "y": 6, "r": 1, "h": 188.13},
{"x": -3, "y": 3, "r": 1, "h": 164.05},
{"x": -5, "y": 1, "r": 1, "h": 141.34}
]
def __init__(self, unit):
self._unit=unit
turtle.speed(1)
def draw_flag(self,color="red"):
turtle.color(color,color)
turtle.goto(-15 * self._unit,10 * self._unit)
turtle.begin_fill()
for _ in range(2):
turtle.forward(30*self._unit)
turtle.right(90)
turtle.forward(20*self._unit)
turtle.right(90)
turtle.end_fill()
def draw_star(self,x=0,y=0,radius=1,angle=90,color="yellow"):
"""
绘制五角星
"""
turtle.color(color, color)
side_length = self._star_side_len_ratio * radius * self._unit
#抬笔,跳到五角星的中心点
turtle.penup()
turtle.goto(x*self._unit, y*self._unit)
turtle.pendown()
turtle.dot(radius/2 * self._unit)
#设置五角星的朝向
turtle.setheading(angle)
#向五角星的朝向前进半径的距离
turtle.forward(radius * self._unit)
turtle.right(180-18)
turtle.begin_fill()
for i in range(5):
turtle.forward(side_length)
turtle.left(72)
turtle.forward(side_length)
turtle.right(144)
turtle.end_fill()
def draw_stars(self):
for circle in self._circles:
self.draw_star(circle["x"],circle["y"],circle["r"],circle["h"])
def draw_red_flag(self):
turtle.title("五星红旗")
self.draw_flag()
self.draw_stars()
turtle.hideturtle()
turtle.done()
if __name__ == "__main__":
redFlag=Draw5StarsFlag(30)
redFlag.draw_red_flag()

完美,打完收工。
253

被折叠的 条评论
为什么被折叠?



