如何在Tkinter Canvas中生成不触碰大圆圈的内嵌小圆圈
无需碰撞检测生成大圆圈内的小圆圈
要让小圆圈完全处于大圆圈内部且不触碰边界,根本不需要循环检测碰撞——直接通过几何计算生成合法的小圆圆心即可,步骤如下:
几何关系梳理
原代码中的大圆圈坐标是(2,2,78,78),换算成几何参数:
- 大圆圆心:
(40, 40)(画布中心) - 大圆半径:
38(直径为78-2=76,半径取半) - 小圆圈尺寸为
20x20,因此小圆半径是10
要保证小圆圈不触碰大圆边界,小圆圆心到大圆圆心的距离必须小于 38-10=28(即大圆半径减去小圆半径)。
实现方法:极坐标随机生成
用极坐标直接生成符合要求的小圆圆心:
- 随机生成0到
2π之间的角度(覆盖大圆圈内所有方向) - 随机生成0到28之间的距离(确保小圆圆心在安全范围内)
- 将极坐标转换为笛卡尔坐标,得到合法的小圆圆心位置
- 基于圆心位置绘制小圆圈
修改后的代码
from tkinter import Tk, Canvas import random as r import math root = Tk() canv = Canvas(master=root, width=80, height=80) # 明确大圆圈的几何参数,替代原有的硬编码坐标 large_circle_center = (40, 40) large_radius = 38 circ1 = canv.create_oval( large_circle_center[0] - large_radius, large_circle_center[1] - large_radius, large_circle_center[0] + large_radius, large_circle_center[1] + large_radius ) canv.pack() small_radius = 10 # 小圆圆心到大圆圆心的最大允许距离 max_center_distance = large_radius - small_radius for _ in range(6): # 生成极坐标参数 angle = r.uniform(0, 2 * math.pi) distance = r.uniform(0, max_center_distance) # 转换为笛卡尔坐标(小圆圆心) small_cx = large_circle_center[0] + distance * math.cos(angle) small_cy = large_circle_center[1] + distance * math.sin(angle) # 绘制小圆圈 canv.create_oval( small_cx - small_radius, small_cy - small_radius, small_cx + small_radius, small_cy + small_radius, outline="black", fill="green" ) root.mainloop()
优势说明
这种方法无需任何碰撞检测逻辑,生成的小圆圈100%符合要求,同时通过极坐标生成的点在大圆圈内分布更均匀,避免了原代码中仅在左上角区域随机的问题。
内容的提问来源于stack exchange,提问作者Shaken not Stirred
相关产品推荐
相关产品推荐

