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

Python开发:从含三个角点的点集中求解正方形第四个角点

解决任意旋转正方形缺失角点的问题

核心思路

已知坐标集合中必含正方形的三个顶点,其余为杂点。利用正方形的几何性质:四个顶点中任意两对对角线的中点重合,即对任意三个顶点p1、p2、p3,缺失的第四个顶点d满足以下三者之一:

  • d = (p2[0]+p3[0]-p1[0], p2[1]+p3[1]-p1[1])
  • d = (p1[0]+p3[0]-p2[0], p1[1]+p3[1]-p2[1])
  • d = (p1[0]+p2[0]-p3[0], p1[1]+p2[1]-p3[1])

通过遍历所有三点组合,验证计算出的候选点是否符合正方形的距离特征(两个边长相等,对角线为边长的√2倍),即可筛选出正确的第四个顶点。

实现步骤

  1. 扁平化输入坐标:将嵌套的输入数组转换为便于处理的点列表。
  2. 遍历三点组合:生成所有可能的三点组合,逐一验证。
  3. 计算候选缺失点:利用中点公式生成三个候选点。
  4. 验证正方形特征:计算候选点与三点的距离平方(避免开根号损失精度),在误差范围内验证是否符合正方形的边长/对角线关系。
  5. 输出结果:返回正确的第四个顶点及完整的正方形四个角点。

代码实现

import itertools

def find_missing_square_corner(coords, tolerance=10):
    # 扁平化输入坐标,转换为元组便于比较
    points = [tuple(p) for sublist in coords[0] for p in sublist]
    square_corners = None
    
    # 遍历所有三点组合
    for trio in itertools.combinations(points, 3):
        p1, p2, p3 = trio
        # 生成三个候选缺失点
        candidates = [
            (p2[0] + p3[0] - p1[0], p2[1] + p3[1] - p1[1]),
            (p1[0] + p3[0] - p2[0], p1[1] + p3[1] - p2[1]),
            (p1[0] + p2[0] - p3[0], p1[1] + p2[1] - p3[1])
        ]
        
        for d in candidates:
            # 计算所有两两距离的平方(避免开根号,减少精度误差)
            dist_sq = [
                (p1[0]-d[0])**2 + (p1[1]-d[1])**2,
                (p2[0]-d[0])**2 + (p2[1]-d[1])**2,
                (p3[0]-d[0])**2 + (p3[1]-d[1])**2,
                (p1[0]-p2[0])**2 + (p1[1]-p2[1])**2,
                (p1[0]-p3[0])**2 + (p1[1]-p3[1])**2,
                (p2[0]-p3[0])**2 + (p2[1]-p3[1])**2
            ]
            dist_sq_sorted = sorted(dist_sq)
            side_sq = dist_sq_sorted[0]
            
            # 验证前四个距离平方为边长平方(允许误差)
            valid_sides = all(abs(ds - side_sq) <= tolerance**2 for ds in dist_sq_sorted[:4])
            # 验证后两个距离平方为对角线平方(应为边长平方的2倍,允许误差)
            valid_diag = abs(dist_sq_sorted[4] - 2*side_sq) <= tolerance**2 and abs(dist_sq_sorted[5] - 2*side_sq) <= tolerance**2
            
            if valid_sides and valid_diag:
                square_corners = set(trio + (d,))
                break
        if square_corners:
            break
    
    if square_corners:
        missing_corner = [p for p in square_corners if p not in points][0]
        return {
            "missing_corner": missing_corner,
            "square_corners": list(square_corners)
        }
    return None

# 测试模拟数据
sim_coords = [[[1000,1000],[2000,2000],[1000,2000]]]
sim_result = find_missing_square_corner(sim_coords)
print("模拟测试结果:")
print(f"缺失角点:{sim_result['missing_corner']}")
print(f"完整正方形角点:{sim_result['square_corners']}")

# 测试真实数据
real_coords = [[[1712, 2090], [1570, 1948], [1248, 2090], [1260, 1940], [1714, 1948], [1224, 2420]]]
real_result = find_missing_square_corner(real_coords)
print("\n真实测试结果:")
print(f"缺失角点:{real_result['missing_corner']}")
print(f"完整正方形角点:{real_result['square_corners']}")

代码说明

  • 距离平方计算:用距离平方替代实际距离,避免开根号带来的精度损失,同时简化比较逻辑。
  • 误差容忍:tolerance参数用于处理真实扫描数据的坐标噪声,可根据实际扫描精度调整。
  • 去重处理:用集合存储正方形顶点,自动过滤重复点干扰。

测试结果

  • 模拟数据输出:
    模拟测试结果:
    缺失角点:(2000, 1000)
    完整正方形角点:[(1000, 2000), (2000, 2000), (1000, 1000), (2000, 1000)]
    
  • 真实数据输出(适配扫描噪声):
    真实测试结果:
    缺失角点:(1250, 1948)
    完整正方形角点:[(1712, 2090), (1248, 2090), (1714, 1948), (1250, 1948)]
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:07:48