You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tkinter Canvas中生成不触碰大圆圈的内嵌小圆圈

无需碰撞检测生成大圆圈内的小圆圈

要让小圆圈完全处于大圆圈内部且不触碰边界,根本不需要循环检测碰撞——直接通过几何计算生成合法的小圆圆心即可,步骤如下:

几何关系梳理

原代码中的大圆圈坐标是(2,2,78,78),换算成几何参数:

  • 大圆圆心:(40, 40)(画布中心)
  • 大圆半径:38(直径为78-2=76,半径取半)
  • 小圆圈尺寸为20x20,因此小圆半径是10

要保证小圆圈不触碰大圆边界,小圆圆心到大圆圆心的距离必须小于 38-10=28(即大圆半径减去小圆半径)。

实现方法:极坐标随机生成

用极坐标直接生成符合要求的小圆圆心:

  1. 随机生成0到2π之间的角度(覆盖大圆圈内所有方向)
  2. 随机生成0到28之间的距离(确保小圆圆心在安全范围内)
  3. 将极坐标转换为笛卡尔坐标,得到合法的小圆圆心位置
  4. 基于圆心位置绘制小圆圈

修改后的代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 07:55:28