若det为零则两直线平行(含重合),否则交点为x=(B1·C2−B2·C1)/det、y=(A2·C1−A1·C2)/det;需先用叉积判平行避免除零,统一用一般式Ax+By+C=0处理竖直线等边界情况。

用叉积判断是否平行,再解二元一次方程
两条直线在平面内要么相交、要么平行(含重合)。C++ 里没有内置“求交点”函数,得自己推导公式并处理边界。核心思路是:把直线写成一般式 Ax + By + C = 0,联立解方程;但先得用叉积快速判平行,避免除零。
常见错误是直接套斜截式 y = kx + b,一遇到竖直线(k 无穷大)就崩。所以统一用向量形式或一般式更稳。
传入两点式参数时,先转一般式系数
假设直线1由点 p1、p2 确定,直线2由 p3、p4 确定,可算出各自的一般式系数:
-
A1 = p2.y - p1.y,B1 = p1.x - p2.x,C1 = p2.x * p1.y - p1.x * p2.y -
A2 = p4.y - p3.y,B2 = p3.x - p4.x,C2 = p4.x * p3.y - p3.x * p4.y
验证:代入 p1 应满足 A1*p1.x + B1*p1.y + C1 == 0(浮点用 abs() 判近似零)。系数顺序影响符号,但不影响解的正确性。
立即学习“C++免费学习笔记(深入)”;
用行列式解交点,注意分母为零的处理
联立 A1*x + B1*y = -C1 和 A2*x + B2*y = -C2,解得:
x = (B1*C2 - B2*C1) / det,y = (A2*C1 - A1*C2) / det,其中 det = A1*B2 - A2*B1
det 实质就是两方向向量的二维叉积。若 abs(det) (比如 <code>1e-9),说明直线平行——此时需额外判断是否重合(代入一点看是否满足另一方程),否则无交点。
性能上,纯算术运算,无循环无分配,毫秒级;兼容所有标准 C++ 版本,不依赖第三方库。
浮点精度和重合直线的坑
实际代码中容易忽略三点:
- 用
double而非float,尤其坐标值较大时(如地图经纬度缩放后) - 判重合不能只靠
det ≈ 0,还要检查p1是否满足直线2方程(即abs(A2*p1.x + B2*p1.y + C2) ) - 交点坐标本身也应加
eps截断(如fabs(x) ),避免输出 <code>-0.000000这类反直觉值
真正麻烦的不是公式,而是把“平行”“重合”“相交”三种情况都稳定区分出来——多数 bug 都出在这里,而不是计算本身。


















