如何避免Python中turtle绘制的随机雪花重叠?
解决雪花绘制重叠问题的方案
要避免雪花重叠,核心思路是跟踪已生成雪花的位置和尺寸,每次生成新雪花前,确保它和所有已存在的雪花保持足够的安全距离。下面是具体的实现方案和修改后的代码:
关键逻辑说明
- 用列表
existing_snowflakes存储每个雪花的中心坐标(x, y)和尺寸(size) - 编写
is_overlapping函数,计算新雪花与已有雪花的中心距离,再和两者的"安全半径"之和对比(根据你的雪花绘制逻辑,安全半径设为size * 15,可根据实际效果调整) - 生成新雪花时,循环生成随机位置和尺寸,直到找到不与任何已有雪花重叠的位置
修改后的完整代码
import time import sys import turtle import random import math restart = True print("This program creates snowflakes. Enjoy!") while restart == True: n = int(input("How many snowflakes do you want?: ")) screen = turtle.Screen() screen.bgcolor("black") speedy = turtle.Turtle() speedy.speed(0) speedy.hideturtle() # 隐藏画笔,让画面更干净 sfcolor = ["yellow","gold","orange","red","violet","magenta","purple","navy","blue","skyblue","cyan","turquoise","lightgreen","green","darkgreen","white","BlueViolet","DeepSkyBlue","snow2","ForestGreen", "gainsboro", "GhostWhite", "goldenrod"] def snowflake(size): speedy.penup() speedy.forward(10 * size) speedy.left(45) speedy.pendown() speedy.color(random.choice(sfcolor)) for i in range(8): branch(size) speedy.left(45) # 绘制完成后回到中心位置,避免影响下一个雪花的定位 speedy.penup() speedy.goto(speedy.xcor() - 10*size*math.cos(math.radians(45)), speedy.ycor() - 10*size*math.sin(math.radians(45))) speedy.pendown() def branch(size): for i in range(3): for i in range(3): speedy.forward(10.0 * size / 3) speedy.back(10.0 * size / 3) speedy.right(45) speedy.left(90) speedy.back(10.0 * size / 3) speedy.left(45) speedy.right(90) speedy.forward(10.0 * size) # 存储已有雪花的(x, y, size)信息 existing_snowflakes = [] # 安全距离系数,可根据实际效果调整 SAFE_FACTOR = 15 def is_overlapping(new_x, new_y, new_size): """检查新雪花是否与已有雪花重叠""" for (x, y, size) in existing_snowflakes: # 计算两个雪花中心的距离 distance = math.hypot(new_x - x, new_y - y) # 两个雪花的安全半径之和 min_safe_distance = (new_size + size) * SAFE_FACTOR if distance < min_safe_distance: return True return False for i in range(n): while True: x = random.randint(-375, 375) y = random.randint(-375, 375) sfsize = random.randint(1, 4) # 检查是否重叠,不重叠则跳出循环 if not is_overlapping(x, y, sfsize): break # 记录这个雪花的信息 existing_snowflakes.append((x, y, sfsize)) # 绘制雪花 speedy.penup() speedy.goto(x, y) speedy.pendown() snowflake(sfsize) print(i+1," Snowflake(s)") restart = False print("Thanks for using the program! You will have the option to restart it shortly.") time.sleep(3) restart = input("Do you want to run the program again? Yes or No: ") restart = restart.upper() if restart == "YES": turtle.Screen().bye() restart = True print("Restarting...") elif restart == "NO": restart = False print("Thank you for using the program. Goodbye!") time.sleep(3) turtle.Screen().bye() sys.exit() else: print("\nError. Program Resetting...") turtle.Screen().bye() print("This program creates snowflakes. Enjoy!") restart = True
额外优化点
- 隐藏了画笔(
speedy.hideturtle()),让雪花画面更整洁 - 绘制完每个雪花后,让画笔回到中心位置,避免影响下一个雪花的坐标定位
- 用
math.hypot计算两点距离,比手动实现勾股定理更简洁
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

