# 绘制五星红旗

"""
国旗制法说明
(1949年9月28日中国人民政治协商会议第一届全体会议主席团公布)
国旗的形状、颜色两面相同,旗上五星两面相对。为便利计,本件仅以旗杆在左之一面为说明之标准。
对于旗杆在右之一面,凡本件所称左均应改右,所称右均应改左。
(一)旗面为红色,长方形,其长与高为三与二之比,旗面左上方缀黄色五角星五颗。一星较大,
    其外接圆直径为旗高十分之三,居左;四星较小,其外接圆直径为旗高十分之一,环拱于大星之右。
    旗杆套为白色。
(二)五星之位置与画法如下:
    甲、为便于确定五星之位置,先将旗面对分为四个相等的长方形,将左上方之长方形上下划为十等分,
    左右划为十五等分。
    乙、大五角星的中心点,在该长方形上五下五、左五右十之处。其画法为:以此点为圆心,
    以三等分为半径作一圆。在此圆周上,定出五个等距离的点,其一点须位于圆之正上方。
    然后将此五点中各相隔的两点相联,使各成一直线。此五直线所构成之外轮廓线,
    即为所需之大五角星。五角星之一个角尖正向上方。
    丙、四颗小五角星的中心点,第一点在该长方形上二下八、左十右五之处,第二点在上四下六、
    左十二右三之处,第三点在上七下三、左十二右三之处,第四点在上九下一、左十右五之处。
    其画法为:以以上四点为圆心,各以一等分为半径,分别作四个圆。在每个圆上各定出五个等距离的点,
    其中均须各有一点位于大五角星中心点与以上四个圆心的各联结线上。然后用构成大五角星的同样方法,
    构成小五角星。此四颗小五角星均各有一个角尖正对大五角星的中心点。
(三)国旗之通用尺度定为如下五种,各界酌情选用:
    甲、长288公分,高192公分。
    乙、长240公分,高160公分。
    丙、长192公分,高128公分。
    丁、长144公分,高96公分。
    戊、长96公分,高64公分。
"""
from turtle import *


"""
print(window_width(),window_height())  # 窗口大小
print(getcanvas())  # 获取画布
print(getscreen())  # 获取screen对象
print(getshapes())  # 查看形状name的列表
print(get_shapepoly())  # 返回形状多边形顶点组成的元组
print(shape())  # 返回或者设置画笔形状
print(screensize()) # 返回当前screen大小
"""



def star(center_point,first_vertex,radius):
    """根据圆心坐标及其第一个顶点坐标绘制五角星"""
    up()
    seth(0)
    goto(center_point)
    angle = towards(first_vertex)
    goto(first_vertex)
    lt(angle)
    rt(90)
    # 确定五个顶点坐标
    five_vertex_points = [first_vertex]
    for _ in range(4):
        circle(-radius,360/5)
        five_vertex_points.append(pos())
    # 开始绘制五角星
    goto(first_vertex)
    color('yellow')
    down()
    begin_fill()
    for index in range(len(five_vertex_points)):
        # delay(10)
        goto(five_vertex_points[(index*2)%len(five_vertex_points)])
    goto(first_vertex)
    end_fill()

def China_Flag(height):
    # 设置高宽
    width = (height/2)*3
    # 设置绘制起点
    start_x = -(width/2)
    start_y = -(height/2)
    up()
    goto(-(width/2),-(height/2))
    down()

    # 绘制矩形旗面
    setheading(0)
    color('red')
    begin_fill()
    for i in range(2):
        fd(width)
        lt(90)
        fd(height)
        lt(90)
    end_fill()
    # 确定五颗星的中心坐标
    five_star_center_points = [(start_x+width/2/15*5,start_y+(1/2+5/20)*height),
                               (start_x+width/2/15*10,start_y+(1/2+8/20)*height),
                               (start_x+width/2/15*12,start_y+(1/2+6/20)*height),
                               (start_x+width/2/15*12,start_y+(1/2+3/20)*height),
                               (start_x+width/2/15*10,start_y+(1/2+1/20)*height),]
    print(five_star_center_points[0])
    # 确定五颗星的第一个顶点坐标
    big_radius = height/2/10*3  # 大五星外接圆半径
    small_radius = height/2/10  # 小五星外接圆半径

    up()
    goto(five_star_center_points[0])
    setheading(90)
    fd(big_radius)
    p = pos()
    print(p)
    first_vertex_points = [p]  # 第一个顶点坐标
    for point in five_star_center_points[1:]:
        goto(point)
        seth(0)
        angle = towards(five_star_center_points[0])
        # down()
        # print(angle)
        lt(angle)
        fd(small_radius)
        first_vertex_points.append(pos())
        up()

    # 绘制五角星
    # 大五角星
    star(five_star_center_points[0], first_vertex_points[0], big_radius)
    print(pos())
    # 4个小五角星
    for i in range(1,5):
        star(five_star_center_points[i],first_vertex_points[i],small_radius)


if __name__ == '__main__':
    # setup(1200,800)  # 窗口大小
    screensize(600, 400)  # 画布大小
    bgcolor('black') # 背景颜色为黑色
    # shape('turtle')
    speed(0)  # 速度为最快
    China_Flag(192)
    hideturtle()
    done()

 最终效果:

 给孩子们讲海龟绘图课的时候,随手画了一个国旗.

效果如下:

 代码:

import turtle
t = turtle.Turtle()

# 定义一个无轨迹移动的goto函数
def my_goto(x,y):
    t.up()
    t.goto(x,y)
    t.down()
# 定义一个绘制五角星的函数   
def wujiaoxing(x,y,leng):
    my_goto(x,y)
    t.begin_fill()
    for i in range(5):
        t.fd(leng)
        t.lt(144)
    t.end_fill()
# 主函数
def main():  
    t.up()
    t.goto(-200,-150)
    t.color('red')
    t.seth(0)
    t.down()

    # 旗面
    for i in range(2):
        t.begin_fill()
        t.fd(300)
        t.lt(90)
        t.fd(200)
        t.lt(90)
        t.end_fill()
    # 五星 
    t.color('yellow')
    wujiaoxing(-148,5.5,30) # 大星
    # 4个小星星
    wujiaoxing(-87,36.5,10) # 大星
    wujiaoxing(-58,17.5,10) # 大星
    wujiaoxing(-58,-5.5,10) # 大星
    wujiaoxing(-87,-40,10) # 大星

main()
t.hideturtle()
t.done()

国旗怎可画得如此草率?

遂下定决心画一个正规的国旗.

step1:

        查阅资料:国旗法

        国旗法中对国旗的绘制方式给出了详细说明,我已附在了,第一部分代码的前面注释部分.

step2:

        因为本案例需要精确控制五星的位置和角度,于是查阅了海龟的文档,确认要使用到的方法如下

turtle.toward(x,y)

        对toward()方法的描述如下:

参数:

  • x – 一个数值或数值对/矢量,或一个海龟实例
  • y – 一个数值——如果 x 是一个数值,否则为 None

返回一个角度,从海龟位置到到 (x,y)的矢量到海龟初始朝向的矢量的夹角。

turtle.position()

 对pos的描述如下:

返回海龟当前位置所在的坐标(x,y),结果是一个元组

 感谢下面的博主的分享:

python库之turtle库官方文档入门_sandalphon4869的博客-CSDN博客_turtle库

 

step3:

        动手绘制

        考虑到代码的可复用性,大部分的参数都通过变量的形式给出.

        计算五颗星的中心坐标:使用果国旗法上的确定方法

        函数说明:

        通过圆心坐标和第一个顶点来确定一个五角星的角度,使用到了toword()方法

def star(center_point,first_vertex,radius):
    """根据圆心坐标及其第一个顶点坐标绘制五角星"""
    up()
    seth(0)
    goto(center_point)
    angle = towards(first_vertex)  # 为确保第一个顶点为五角星的正方向
    goto(first_vertex)
    lt(angle)
    rt(90)
    # 确定五个顶点坐标
    five_vertex_points = [first_vertex]
    for _ in range(4):
        circle(-radius,360/5)
        five_vertex_points.append(pos())
    # 开始绘制五角星
    goto(first_vertex)
    color('yellow')
    down()
    begin_fill()
    for index in range(len(five_vertex_points)):
        # delay(10)
        goto(five_vertex_points[(index*2)%len(five_vertex_points)])
    goto(first_vertex)
    end_fill()

确定4颗小星星的第一个顶点坐标,同样使用了toward()方法,使海龟朝向大星的中心点,向前移动小星外接圆半径长度,记录下坐标,即为小星的第一个顶点位置

    # 确定五颗星的第一个顶点坐标
    big_radius = height/2/10*3  # 大五星外接圆半径
    small_radius = height/2/10  # 小五星外接圆半径

    up()
    goto(five_star_center_points[0])
    setheading(90)
    fd(big_radius)
    p = pos()
    print(p)
    first_vertex_points = [p]  # 第一个顶点坐标
    for point in five_star_center_points[1:]:
        goto(point)
        seth(0)
        angle = towards(five_star_center_points[0])
        # down()
        # print(angle)
        lt(angle)
        fd(small_radius)
        first_vertex_points.append(pos()) # 追加小星第一个顶点坐标到一个列表
        up()

根据中心点和第一个顶点来找其他五等分点,我使用的方法是循环画圆,每一次循环画1/5的圆弧,然后记录顶点坐标.
 

# 确定五个顶点坐标
    five_vertex_points = [first_vertex]
    for _ in range(4):
        circle(-radius,360/5)
        five_vertex_points.append(pos())

找到五个等分点以后,通过循环,绘制五角星.顺序如下0->2->4->1->3,这里我使用的是求模运算

    down()
    begin_fill()
    for index in range(len(five_vertex_points)):
        # delay(10)
        goto(five_vertex_points[(index*2)%len(five_vertex_points)])
    goto(first_vertex)
    end_fill()

总结:

第一次定义star()函数时没有使用toward()方法,导致角度出错,没有绘制成功.


35岁学python,也不直到为了啥?

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐