Python中如何通过x,y位移序列检测正方形而无需枚举所有配置
你可以通过验证正方形位移序列的固有几何属性来判断,完全不需要提前枚举所有起点和方向的配置,具体判断逻辑如下:
核心判断条件
满足以下所有条件的位移序列即为正方形:
- 位移列表长度为4(对应正方形的4条边)
- 4段位移的模长完全相等(且不为0):对每个位移
(x,y),计算x² + y²,4个值的误差在可接受范围内即可 - 相邻位移两两垂直:相邻两个位移向量的点积为0(误差范围内接近0即可),计算方式为:位移1
(x1,y1)和位移2(x2,y2)的点积 =x1*x2 + y1*y2,最后一段位移需要和第一段位移也满足垂直要求 - 旋转方向完全一致:相邻两个位移的叉积符号统一(全正或全负),叉积计算方式为
x1*y2 - x2*y1,符号一致代表全程都是顺时针/逆时针旋转,没有反向拐点 - 总位移为0:所有位移的x坐标相加总和为0、y坐标相加总和为0,代表绘制结束后回到了起点,图形闭合
Python 实现示例
def is_square(moves, tolerance=1e-6): # 条件1:长度为4 if len(moves) != 4: return False # 条件2:所有位移模长相等 norms = [x**2 + y**2 for x,y in moves] if abs(max(norms) - min(norms)) > tolerance: return False if norms[0] < tolerance: # 排除零位移 return False # 条件3:相邻垂直 + 条件4:叉积符号统一 + 条件5:总位移为0 total_x = total_y = 0 cross_sign = None for i in range(4): x1, y1 = moves[i] x2, y2 = moves[(i+1)%4] # 点积判断垂直 dot = x1*x2 + y1*y2 if abs(dot) > tolerance: return False # 叉积判断方向 cross = x1*y2 - x2*y1 current_sign = 1 if cross > tolerance else (-1 if cross < -tolerance else 0) if current_sign == 0: return False if cross_sign is None: cross_sign = current_sign else: if current_sign != cross_sign: return False # 累加总位移 total_x += x1 total_y += y1 # 总位移为0判断 if abs(total_x) > tolerance or abs(total_y) > tolerance: return False return True
适配实际场景的优化
因为实际鼠标追踪会有手势误差,你可以根据需要调整tolerance参数的大小,允许微小的数值偏差,不用严格等于0。
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

