用Python turtle画出标准五星红旗,原来国旗绘制有这么多数学奥秘!

用Python turtle画出标准五星红旗,原来国旗绘制有这么多数学奥秘!

用代码向祖国致敬,用数学诠释庄严

一、从五角星到国旗:一个程序员的突发奇想

昨天深夜,在网上看到一个有趣的Python项目------用turtle模块绘制五角星。看着屏幕上逐渐成型的黄色星星,一个想法突然闪过:既然能画五角星,为什么不画一面完整的五星红旗呢?

然而,当我开始动手时,却发现这不仅仅是画几个星星那么简单。国旗的绘制有着严格的标准和比例,每一颗星星的位置、角度、大小都必须精确无误。这不禁让我思考:用代码绘制国旗,到底需要哪些数学知识?

二、五星红旗的数学密码

2.1 国旗的基本规格

根据《中华人民共和国国旗法》和国旗制作标准,五星红旗的规格如下:

  • 长宽比:3:2
  • 主色调:红色(RGB: 238, 28, 36)和黄色(RGB: 255, 215, 0)
  • 五颗星的位置:精确的几何定位
  • 星星的大小比例:大星外接圆直径是旗高的3/10,小星是1/10

2.2 星星定位的数学原理

五星红旗上五颗星的位置不是随意摆放的,而是基于黄金分割和几何学的精密计算:

复制代码
大五角星中心点位置:
x坐标 = 旗面宽度 × 1/4
y坐标 = 旗面高度 × 3/4

四颗小五角星与大星的相对位置:
1号小星:与大星中心连线与水平线夹角 0°
2号小星:夹角 18°
3号小星:夹角 36°
4号小星:夹角 54°

三、代码实现:从零绘制五星红旗

3.1 基础工具:turtle模块快速入门

在开始绘制之前,让我们先熟悉一下turtle模块的几个核心功能:

python 复制代码
import turtle

# 1. 画布设置
turtle.setup(900, 600)  # 设置窗口大小
turtle.screensize(900, 600, "white")  # 设置画布大小和背景

# 2. 画笔控制
turtle.pensize(3)  # 设置画笔粗细
turtle.pencolor(1, 0, 0)  # 设置画笔颜色(RGB格式)
turtle.fillcolor(1, 1, 0)  # 设置填充颜色

# 3. 基本绘图命令
turtle.forward(100)  # 向前移动100像素
turtle.right(72)  # 向右转72度
turtle.penup()  # 抬笔,移动时不画线
turtle.pendown()  # 落笔,移动时画线

3.2 五角星绘制类:封装的艺术

为了让代码更加模块化和可复用,我设计了一个五角星绘制类:

python 复制代码
import turtle
import math

class FivePointedStar:
    """五角星绘制类"""
    
    def __init__(self, circumradius, center=(0, 0), rotation=0, 
                 pen_color="yellow", fill_color="yellow"):
        """
        初始化五角星
        
        参数:
            circumradius: 外接圆半径
            center: 中心点坐标 (x, y)
            rotation: 旋转角度(度),0表示一个角尖朝上
            pen_color: 画笔颜色
            fill_color: 填充颜色
        """
        self.circumradius = circumradius
        self.center = center
        self.rotation = rotation
        self.pen_color = pen_color
        self.fill_color = fill_color
        
        # 计算五角星边长(根据外接圆半径)
        self.side_length = 2 * circumradius * math.sin(math.radians(36))
    
    def draw_star(self):
        """绘制一个五角星"""
        x, y = self.center
        
        # 移动到起点
        turtle.penup()
        turtle.goto(x, y - self.circumradius)
        turtle.setheading(90 + self.rotation)  # 设置朝向
        turtle.pendown()
        
        # 设置颜色
        turtle.color(self.pen_color, self.fill_color)
        
        # 开始填充
        turtle.begin_fill()
        
        # 绘制五角星
        for _ in range(5):
            turtle.forward(self.side_length)
            turtle.right(144)  # 五角星内角为144度
            turtle.forward(self.side_length)
            turtle.left(72)  # 转向下一个顶点
        
        # 结束填充
        turtle.end_fill()
    
    def __call__(self):
        """使实例可调用"""
        self.draw_star()
        return self

3.3 完整五星红旗绘制实现

基于国旗标准和上面的五角星类,我们可以实现完整的国旗绘制:

python 复制代码
import turtle
import math

class NationalFlag:
    """五星红旗绘制类"""
    
    def __init__(self, width=900, height=600):
        """
        初始化国旗
        
        参数:
            width: 旗面宽度
            height: 旗面高度
        """
        self.width = width
        self.height = height
        
        # 国旗颜色标准RGB值
        self.RED = (0.93, 0.11, 0.14)  # 红色
        self.YELLOW = (1.0, 0.84, 0.0)  # 黄色
        
        # 计算基本尺寸
        self.grid_width = width / 30  # 网格宽度(1/15旗宽)
        self.grid_height = height / 20  # 网格高度(1/10旗高)
        
        # 星星尺寸
        self.big_star_radius = height * 0.15  # 大星半径 = 旗高 * 3/20
        self.small_star_radius = height * 0.05  # 小星半径 = 旗高 * 1/20
        
        # 星星位置(基于网格坐标)
        self.star_positions = [
            # 大五角星位置
            {
                "type": "big",
                "grid_x": 5,  # 第5格
                "grid_y": 5,  # 第5格
                "center": (0, 0)  # 临时占位
            },
            # 四颗小五角星位置
            {
                "type": "small",
                "grid_x": 10,  # 第10格
                "grid_y": 2,   # 第2格
                "angle": 0,    # 与大星连线角度
                "center": (0, 0)
            },
            {
                "type": "small",
                "grid_x": 12,
                "grid_y": 4,
                "angle": 18,
                "center": (0, 0)
            },
            {
                "type": "small", 
                "grid_x": 12,
                "grid_y": 7,
                "angle": 36,
                "center": (0, 0)
            },
            {
                "type": "small",
                "grid_x": 10,
                "grid_y": 9,
                "angle": 54,
                "center": (0, 0)
            }
        ]
        
        # 初始化turtle
        self.init_turtle()
    
    def init_turtle(self):
        """初始化turtle设置"""
        turtle.setup(self.width + 100, self.height + 100)
        turtle.title("五星红旗 - 中华人民共和国国旗")
        turtle.speed(0)  # 最快速度
        turtle.hideturtle()  # 隐藏海龟箭头
    
    def grid_to_pixel(self, grid_x, grid_y):
        """
        将网格坐标转换为像素坐标
        
        国旗左上角为原点(0,0),向右为x正方向,向下为y正方向
        网格系统:横轴15格,纵轴10格
        """
        pixel_x = grid_x * self.grid_width
        pixel_y = grid_y * self.grid_height
        
        # 转换为turtle坐标系(中心为原点)
        turtle_x = pixel_x - self.width / 2
        turtle_y = self.height / 2 - pixel_y
        
        return turtle_x, turtle_y
    
    def draw_background(self):
        """绘制红色背景"""
        turtle.penup()
        turtle.goto(-self.width/2, self.height/2)  # 左上角
        turtle.pendown()
        
        turtle.fillcolor(self.RED)
        turtle.begin_fill()
        
        # 绘制矩形
        for _ in range(2):
            turtle.forward(self.width)
            turtle.right(90)
            turtle.forward(self.height)
            turtle.right(90)
        
        turtle.end_fill()
    
    def calculate_star_centers(self):
        """计算所有星星的中心坐标"""
        # 计算大星中心
        big_star = self.star_positions[0]
        big_star["center"] = self.grid_to_pixel(
            big_star["grid_x"], 
            big_star["grid_y"]
        )
        
        # 计算小星中心
        for i in range(1, 5):
            star = self.star_positions[i]
            star["center"] = self.grid_to_pixel(
                star["grid_x"],
                star["grid_y"]
            )
            
            # 计算小星需要旋转的角度(角尖指向大星中心)
            dx = big_star["center"][0] - star["center"][0]
            dy = big_star["center"][1] - star["center"][1]
            angle_to_big = math.degrees(math.atan2(dy, dx))
            
            # 五角星默认一个角尖朝上(-90度),需要调整
            star["rotation"] = angle_to_big - 90
    
    def draw_stars(self):
        """绘制所有五角星"""
        # 绘制大五角星
        big_star = self.star_positions[0]
        star = FivePointedStar(
            circumradius=self.big_star_radius,
            center=big_star["center"],
            rotation=0,  # 大星一个角尖正朝上
            pen_color=self.YELLOW,
            fill_color=self.YELLOW
        )
        star()
        
        # 绘制四颗小五角星
        for i in range(1, 5):
            small_star = self.star_positions[i]
            star = FivePointedStar(
                circumradius=self.small_star_radius,
                center=small_star["center"],
                rotation=small_star["rotation"],  # 小星角尖指向大星
                pen_color=self.YELLOW,
                fill_color=self.YELLOW
            )
            star()
    
    def draw_grid_lines(self, show_grid=False):
        """绘制辅助网格线(调试用)"""
        if not show_grid:
            return
            
        turtle.penup()
        turtle.pencolor(0.8, 0.8, 0.8)  # 浅灰色
        turtle.pensize(1)
        
        # 绘制水平网格线
        for i in range(11):  # 0-10共11条线
            y = self.height/2 - i * self.grid_height
            turtle.goto(-self.width/2, y)
            turtle.pendown()
            turtle.goto(self.width/2, y)
            turtle.penup()
        
        # 绘制垂直网格线
        for i in range(16):  # 0-15共16条线
            x = -self.width/2 + i * self.grid_width
            turtle.goto(x, self.height/2)
            turtle.pendown()
            turtle.goto(x, -self.height/2)
            turtle.penup()
    
    def draw_flag(self, show_grid=False):
        """绘制完整的五星红旗"""
        # 1. 计算星星位置
        self.calculate_star_centers()
        
        # 2. 绘制红色背景
        self.draw_background()
        
        # 3. 绘制辅助网格(可选)
        self.draw_grid_lines(show_grid)
        
        # 4. 绘制五角星
        self.draw_stars()
        
        # 5. 完成绘图
        turtle.done()
    
    def save_image(self, filename="national_flag.png"):
        """保存国旗图片"""
        canvas = turtle.getcanvas()
        canvas.postscript(file=filename.replace('.png', '.eps'))
        
        # 如果需要PNG格式,可以使用PIL转换
        try:
            from PIL import Image
            img = Image.open(filename.replace('.png', '.eps'))
            img.save(filename, "PNG")
            print(f"国旗已保存为: {filename}")
        except ImportError:
            print(f"EPS文件已保存,如需PNG格式请安装PIL库")

# 主程序
if __name__ == "__main__":
    print("开始绘制五星红旗...")
    print("国旗比例: 3:2")
    print("大五角星半径: 旗高的3/20")
    print("小五角星半径: 旗高的1/20")
    print("-" * 40)
    
    # 创建国旗对象
    flag = NationalFlag(width=900, height=600)
    
    # 绘制国旗(show_grid=True可以显示辅助网格)
    flag.draw_flag(show_grid=False)
    
    # 保存图片
    # flag.save_image("china_flag.png")
    
    print("五星红旗绘制完成!")

四、关键代码解析

4.1 坐标系统转换

这是整个项目的核心难点之一。我们需要在三种坐标系之间转换:

python 复制代码
def grid_to_pixel(self, grid_x, grid_y):
    """
    坐标转换三部曲:
    1. 网格坐标 → 像素坐标(左上角原点)
    2. 像素坐标 → 标准化坐标(0-1范围)
    3. 标准化坐标 → turtle坐标(中心原点)
    """
    # 步骤1:网格转像素
    pixel_x = grid_x * self.grid_width
    pixel_y = grid_y * self.grid_height
    
    # 步骤2&3:转换为turtle坐标系
    turtle_x = pixel_x - self.width / 2
    turtle_y = self.height / 2 - pixel_y
    
    return turtle_x, turtle_y

4.2 星星方向计算

小五角星的角尖需要精确指向大五角星中心,这涉及向量角度计算:

ini 复制代码
# 计算从当前小星指向大星的向量
dx = big_star_x - small_star_x
dy = big_star_y - small_star_y

# 计算向量角度(弧度)
angle_rad = math.atan2(dy, dx)

# 转换为角度,并调整使得角尖指向大星
rotation_angle = math.degrees(angle_rad) - 90

4.3 五角星几何算法

绘制完美的正五角星需要精确的几何计算:

ini 复制代码
# 五角星边长与外接圆半径的关系
# 公式:边长 = 2 * 半径 * sin(36°)
side_length = 2 * radius * math.sin(math.radians(36))

# 绘制时的旋转角度
# 内角:144°,外角:72°
for _ in range(5):
    turtle.forward(side_length)
    turtle.right(144)  # 转向绘制下一个角

五、国旗绘制的数学之美

5.1 黄金分割的应用

五星红旗的设计中蕴含了黄金分割比例(φ ≈ 1.618):

ini 复制代码
旗面长宽比 = 3:2 = 1.5(接近黄金比例)

大星中心位置:
距左 = 旗宽 × 1/4
距上 = 旗高 × 3/4

这些比例都接近或等于黄金分割比例

5.2 星星布局的几何学

四颗小星的布局形成了一个圆弧,这个大圆弧的圆心正是大五角星的中心,形成了和谐统一的视觉效果。

六、扩展应用与思考

6.1 代码优化方向

  1. 性能优化 :使用turtle.tracer(0)关闭动画,最后调用turtle.update()一次性更新
  2. 交互功能:添加点击缩放、拖动查看细节等功能
  3. 参数化设计:允许自定义国旗尺寸、颜色等参数

6.2 数学教育的绝佳案例

这个项目不仅是编程实践,更是生动的数学教学案例:

  • 几何学:正五角星的绘制
  • 三角函数:角度计算、坐标转换
  • 比例与缩放:国旗的标准比例
  • 坐标系:不同坐标系统的转换

6.3 进阶挑战

如果你已经掌握了基本绘制,可以尝试这些进阶挑战:

  1. 动画绘制:让五角星一颗颗逐渐显示
  2. 3D国旗:使用三维图形库绘制飘扬的国旗
  3. 国旗知识问答:结合绘制过程,进行国旗知识科普
  4. 多种国旗绘制:实现世界各国国旗的绘制

七、总结

通过Python的turtle模块绘制五星红旗,不仅是一次编程实践,更是一次深刻的爱国主义教育和数学美学体验。每一行代码都蕴含着对国旗标准的尊重,每一个函数都体现了数学的精确与优雅。

国旗的绘制标准是严格的,但代码的实现可以是灵活的。在遵循国旗法规定的前提下,我们可以用编程语言表达对祖国的热爱,用数学公式诠释国旗的庄严。

代码不仅是工具,也可以是艺术的表达;数学不仅是公式,也可以是美的呈现。


注意事项

  1. 本项目代码遵循《中华人民共和国国旗法》相关规定
  2. 国旗的绘制必须严格按照国家标准比例
  3. 本代码仅用于教育和学习目的
  4. 实际使用国旗时应遵守相关法律法规

用代码致敬祖国,用技术传承文化。每一次绘制,都是对国旗庄严的再认识;每一行代码,都是对祖国深情的再表达。

相关推荐
亲爱的非洲野猪2 小时前
Java线程池深度解析:从原理到最佳实践
java·网络·python
用户1377940499932 小时前
基于遗传算法实现自动泊车+pygame可视化
python
4***17542 小时前
强化学习中的蒙特卡洛方法
python
pen-ai2 小时前
打通 Python 与 C++ 的参数传递机制
开发语言·c++·python
至此流年莫相忘2 小时前
Python之深拷贝和浅拷贝
python
像风一样自由20203 小时前
XGBoost、LightGBM、CatBoost 原理深度剖析与全面对比
python
用户230826676653 小时前
Python的管道符(|)联合类型语法糖
python
东木月3 小时前
使用python获取Windows产品标签
开发语言·windows·python
AIFQuant3 小时前
2026 越南证券交易所(VN30, HOSE)API 接口指南
大数据·后端·python·金融·restful