PrepStack · Markdown HTML

几何向量 / 叉积与方向

几何、扫描线、模拟与解析 · HTML

数学 / 逻辑形态

cross(OA,OB)=ax*by-ay*bx;符号给左转/右转/共线,点积给夹角与投影方向。

识别信号

容易误判的相似信号

SignalWhy it is different
只比较包围盒包围盒重叠不是线段相交的充分条件,还需方向测试。
浮点直接判零几何输入为浮点时需 epsilon 或稳健谓词,不能直接 ==0。

核心不变量

叉积符号在同一坐标方向与点序约定下稳定表示有向转角;共线特例再用坐标范围判断在线段上。

状态、转移与处理顺序

ItemDefinition
State点坐标、方向值 o1..o4、边界包含策略与数值容差。
Transition对三点计算 orientation;一般相交要求两段端点分别跨越对方直线,零值进入 on_segment。
Frontier / order无搜索前沿;每个局部几何关系由有限个精确谓词汇总。

Python 骨架

def cross(a, b, c):
    return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])

def on_segment(a, b, p):
    return (cross(a,b,p) == 0 and
            min(a[0],b[0]) <= p[0] <= max(a[0],b[0]) and
            min(a[1],b[1]) <= p[1] <= max(a[1],b[1]))

def segments_intersect(a, b, c, d):
    x1, x2, x3, x4 = cross(a,b,c), cross(a,b,d), cross(c,d,a), cross(c,d,b)
    if ((x1 > 0 > x2 or x2 > 0 > x1) and
        (x3 > 0 > x4 or x4 > 0 > x3)):
        return True
    return (x1 == 0 and on_segment(a,b,c) or
            x2 == 0 and on_segment(a,b,d) or
            x3 == 0 and on_segment(c,d,a) or
            x4 == 0 and on_segment(c,d,b))

正确性思路

  1. 叉积是两个向量张成平行四边形的有向面积,符号对应转向。
  2. 非共线相交时每条线段的端点位于另一支撑线两侧。
  3. 该两侧条件对两条线段同时成立时交点落在二者内部。
  4. 叉积为零时,on_segment 的包围范围恰处理端点与重叠特例。

复杂度

TimeSpaceParameters
每次方向或线段相交判断 O(1)O(1)坐标数值范围决定整数溢出或浮点容差策略

边界条件

错误模式

PatternWhy it fails / fix
使用斜率相除竖线除零且浮点误差放大。
漏掉共线特例严格跨越测试不会覆盖端点接触。
点序不一致交换参数会翻转叉积符号。

选择与排除规则

相关模板

RelationTemplateBoundary
全局扩展扫描线 + 事件排序要在大量几何对象中按坐标处理事件
运动判定显式模拟 / 状态机模拟中每步需要几何碰撞谓词
凸形组合相向双指针有序边界上做旋转卡壳类扫描

原创微型例子

环节内容
Result两组端点叉积异号,判定相交。
Scenario线段 (0,0)-(4,4) 与 (0,4)-(4,0)。
Walkthrough每段的两个端点分别位于另一支撑线两侧,交点为 (2,2)。

Recall prompts

我的补充