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

Python Turtle三角形海龟碰撞检测:distance函数未考虑形状尺寸

Turtle海龟重叠检测解决方案

针对你遇到的distance()仅计算海龟中心距离、无法识别图形边缘重叠的问题,提供两种可行方案:

一、快速外接圆碰撞检测

适合对精度要求不高的场景,通过计算海龟图形的外接圆半径,判断两圆是否相交(中心距离小于两半径之和)。

代码示例

import turtle

att = turtle.Turtle()
dif = turtle.Turtle()
dif.shape("triangle")
dif.color("red")
dif.shapesize(stretch_wid=2, stretch_len=2)

reference = att.heading()
startpoint = att.position()
dif_pos = dif.position()    

Aod = turtle.Turtle()
Aod.penup()
Aod.color("green")
Aod.shape("triangle")
Aod.shapesize(stretch_wid=15, stretch_len=15)    
Aod.setheading(reference + 180)
Aod.goto(startpoint)
Aod.forward(-170)

# 计算海龟的碰撞外接圆半径
def get_collision_radius(t):
    # 默认海龟基准形状的中心到顶点距离约为10像素
    base_radius = 10
    # 取宽/长缩放的最大值作为实际缩放倍数
    scale = max(t.shapesize()[0], t.shapesize()[1])
    return base_radius * scale

aod_radius = get_collision_radius(Aod)
dif_radius = get_collision_radius(dif)
current_distance = Aod.distance(dif)

if current_distance < (aod_radius + dif_radius):
    print(f"当前距离: {current_distance}")
    print("检测到重叠/碰撞")
else:
    print(f"当前距离: {current_distance}")
    print("无重叠")

二、精确三角形碰撞检测(分离轴定理)

针对三角形海龟,通过获取图形的实际顶点坐标,使用分离轴定理判断两个三角形是否相交,能准确识别边缘接触的情况。

代码示例

import turtle
import math

# 获取海龟在世界坐标系中的形状顶点
def get_world_vertices(t):
    poly = t.get_shapepoly()
    stretch_wid, stretch_len, _, _ = t.shapesize()
    x0, y0 = t.position()
    heading_rad = math.radians(t.heading())
    cos_h = math.cos(heading_rad)
    sin_h = math.sin(heading_rad)
    
    vertices = []
    for x, y in poly:
        # 缩放坐标:x对应朝向方向缩放,y对应垂直朝向方向缩放
        scaled_x = x * stretch_len
        scaled_y = y * stretch_wid
        # 旋转坐标适配海龟朝向
        rotated_x = scaled_x * cos_h - scaled_y * sin_h
        rotated_y = scaled_x * sin_h + scaled_y * cos_h
        # 平移到海龟当前位置
        world_x = rotated_x + x0
        world_y = rotated_y + y0
        vertices.append((world_x, world_y))
    return vertices

# 分离轴定理判断两个三角形是否相交
def triangles_intersect(tri1, tri2):
    # 获取边的法向量作为分离轴
    def edge_normal(pt1, pt2):
        dx = pt2[0] - pt1[0]
        dy = pt2[1] - pt1[1]
        return (-dy, dx)
    
    # 将点集投影到轴上,返回极值
    def project(points, axis):
        min_proj = max_proj = points[0][0] * axis[0] + points[0][1] * axis[1]
        for p in points[1:]:
            proj = p[0] * axis[0] + p[1] * axis[1]
            if proj < min_proj:
                min_proj = proj
            if proj > max_proj:
                max_proj = proj
        return min_proj, max_proj
    
    # 判断两个投影区间是否重叠
    def overlap(min1, max1, min2, max2):
        return not (max1 < min2 or max2 < min1)
    
    # 收集所有需要检测的分离轴
    axes = []
    for i in range(3):
        axes.append(edge_normal(tri1[i], tri1[(i+1)%3]))
        axes.append(edge_normal(tri2[i], tri2[(i+1)%3]))
    
    # 检查每个轴,若存在分离轴则不相交
    for axis in axes:
        min1, max1 = project(tri1, axis)
        min2, max2 = project(tri2, axis)
        if not overlap(min1, max1, min2, max2):
            return False
    return True

# 测试逻辑
att = turtle.Turtle()
dif = turtle.Turtle()
dif.shape("triangle")
dif.color("red")
dif.shapesize(stretch_wid=2, stretch_len=2)

reference = att.heading()
startpoint = att.position()

Aod = turtle.Turtle()
Aod.penup()
Aod.color("green")
Aod.shape("triangle")
Aod.shapesize(stretch_wid=15, stretch_len=15)    
Aod.setheading(reference + 180)
Aod.goto(startpoint)
Aod.forward(-170)

# 获取两个海龟的三角形顶点
aod_tri = get_world_vertices(Aod)
dif_tri = get_world_vertices(dif)

if triangles_intersect(aod_tri, dif_tri):
    print("检测到三角形重叠")
else:
    print("无三角形重叠")

turtle.done()

方案说明

  • 外接圆方案代码简洁、计算快,适合实时性要求高的场景;
  • 分离轴定理方案精度高,能准确识别边缘接触,但计算量稍大,适合需要精确碰撞判断的场景。

内容的提问来源于stack exchange,提问作者Stefano Menicocci

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:23:13