图解实验室 / 入门进阶 · 16 分钟 · 数学几何
二维叉积:点在有向直线的哪一侧?
先把 A 搬到原点,再看两项乘积的差。交换 A、B,左右会反过来;共线不等于在线段内。
固定比例坐标舞台 · 每格 2 单位
先看方向:箭头从 A 指向 B,数学坐标 y 向上。 A=(-3, -2),B=(3, 1),C=(0, 4)。det=27。LEFT:从 A 看向 B,C 在左侧。C 不在闭线段 AB 内。
p = 6 × 6 = 36;q = 3 × 3 = 9。det = (Bx−Ax)(Cy−Ay) − (By−Ay)(Cx−Ax) = 27;有向面积 = 13.5
// 向量记号:u = B − A, v = C − A;以下逐坐标计算所有步使用同一坐标比例。减少动画偏好会关闭平移过渡;无自动播放。输入仅在浏览器内,不写入 URL 或持久化。
“在线上”为什么还不够?
det=0 只说明 A、B、C 共线。判断 C 是否在闭线段 AB 内,还要同时落在两个坐标的端点包围范围内。A=B 时有向直线不存在;闭线段则退化为单点,仅 C=A 时属于它。
大整数反例:肉眼几乎共线,答案却不是 TOUCH
A=(0,0),B=(10⁹,10⁹−1),C=(10⁹−1,10⁹−2)。两项乘积很接近,但精确 det=−1,结果 RIGHT。Number 的乘法可能丢掉这一差值;每个坐标先转 BigInt,再相减相乘。此大数例仅作精确计算说明,不伪装成按小坐标比例可见的图形。
看完图,带走这些结论
先取 u=B−A、v=C−A,再计算 det=ux·vy−uy·vx。数学坐标 y 向上时,det>0 表示从 A 看向 B 的左侧,det<0 表示右侧,det=0 表示共线。A=B 没有有向直线,方向未定义。det/2 是三角形 ABC 的有向面积,长度单位平方。
适用条件与边界
坐标模型接收三个二维安全整数点,并在相减前把每个坐标转成 BigInt;负零按零处理。交互图只接受−6到6整数,横纵每单位同长、数学y向上,平移前后比例固定。CSES2189保证A≠B,本课额外明确退化情况。TOUCH是该题的共线输出词,不意味着C位于线段AB内。
始终保持的规律
同一平移不改变向量差和det;图形始终采用y向上且横纵同尺度坐标。A≠B时符号定义左右,交换A/B反号;有向面积为det/2,通常几何面积为|det|/2。
逐步例子
- 原创示例A=(−3,−2)、B=(3,1)、C=(0,4)。将三个点同时减去A,得到u=(6,3)、v=(3,6)。这只是平移,方向和三角形面积均不变。
- 计算p=6×6=36、q=3×3=9;det=p−q=27,所以C在A→B左侧,有向面积13.5。图中的两框表示乘积,几何面积按绝对值绘制,乘积文字保留正负。
- 为什么两项相减?以共同原点的u、v组成平行四边形,其有向面积是ux·vy−uy·vx;三角形只有一半。交换u、v会改变朝向并使符号反转。
- 交换A与B后,以新的起点重算两条向量;det(B,A,C)=−det(A,B,C),有向直线左右颠倒。整体平移不改变det;统一放大s倍使det乘s²。
- det=0只说明共线。A=(−2,0)、B=(1,0)、C=(4,0)仍输出TOUCH,但C不在线段内。线段内还须满足min(Ax,Bx)≤Cx≤max(Ax,Bx),且y坐标也在包围范围内。
- C=A或C=B在A≠B时合法且共线;A=B时没有观察方向,方向返回UNDEFINED。退化闭线段为单点,仅C=A时属于它。
- 大整数反例A=(0,0)、B=(10⁹,10⁹−1)、C=(10⁹−1,10⁹−2)的精确det=−1。两个约10¹⁸乘积相减,不能用Number近似零判断;本课先逐坐标转BigInt,再作全部算术。
- 应用:2026年10月24日的AtCoder ABC481 E要求选一条过原点、但不经过任何星点的直线,再选一侧使星数尽量多。固定非零方向u,把A设为原点、B设为u,便可逐点计算det(u,P)。例如u=(1,−1),官方首组样例的四点(2,1)、(2,−1)、(−1,2)、(−2,−3)依次得到3、1、1、−5,因此这条线两侧为3颗和1颗。
- 这只是固定方向的判侧应用,不是ABC481 E的完整最优方向算法,也不能仅凭一次计数证明全局最优。u改为−u只会交换左右计数,不改变两侧较大值;若某点det=0,该候选直线经过星点,在此题中非法,不能把它随意分给任一侧。u=(0,0)根本不定义方向。原题还需寻找最优的合法方向;本课不实现这一步,也不把竞赛题出现当作搜索热度证据。
精确计算与复杂度
每组三点使用固定次数的减法和乘法。在固定宽度整数模型中为O(1)时间、O(1)额外空间;BigInt的位运算成本仍随整数位数增长,不能宣称任意精度运算绝对常数时间。输入为Number时必须先确认每个坐标是安全整数;已经舍入的大整数无法靠BigInt补救。必须在相减前转换,因为两个安全整数之差也可能不安全。浮点测量坐标不在本课精确整数模型内,不能随意套固定epsilon。
常见误区
- 把屏幕向下的y坐标直接套进数学左右判定,导致符号倒转
- 只计算斜率:竖直线除零,且不同方向容易混淆
- 把TOUCH共线误当成在线段内,漏掉包围范围检查
- A=B仍强行声称左侧或右侧
- 先用Number相减/相乘再转BigInt,精度已无法恢复
- 用BigInt除2截断半整数面积,或把负有向面积当负几何面积
自测与答案
A=(0,0)、B=(2,0)、C=(5,0)的det和线段归属是什么?交换A/B呢?
det=0,方向输出TOUCH(共线),但C不在线段AB内。交换A/B仍为0;若C不共线,交换方向才表现为LEFT/RIGHT互换。