Python Turtle海龟画图-画五星红旗3-正式画五星红旗

上回咱们试着画了五星红旗的辅助线和辅助圆,这样帮助咱们理解了五角星的坐标。

这回咱们正式来画五星红旗,画五星红旗最难的地方在于算出来右侧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()

完美,打完收工。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值