求两直线交点算法
有中间交点 CD在AB异侧 且AB在CD异侧
AB在CD异侧 但 CD在AB同侧 无中间交点
A
B
×
A
C
A
B
×
A
D
\nobreak AB \times AC \newline AB \times AD
AB×ACAB×AD
异号
叉乘后相乘小于零
等于零的几种情况
A = B
C与AB共线
D与AB共线
求交点,可由面积比例用叉乘计算
C E C D = S A B C S A B C ′ \frac{CE}{CD} =\frac{S_{ABC}}{S_{ABC'}} CDCE=SABC′SABC
综上 代码部分
float cross(float* A, float* B, float* C, float* D)
{
return (B[0] - A[0]) * (D[1] - C[1]) - (B[1] - A[1]) * (D[0] - C[0]);
}
void copyPoint(float* dst, float *src)
{
dst[0] = src[0];
dst[1] = src[1];
}
// EPS 误差自定 等零用线段长度点到直线距离替换
int intersect(float* a, float *b, float *c, float *d, float* res)
{
if (a[0] == b[0] && a[1] == b[1]) // ab同一点
return 0;
float a1 = cross(a,b,a,c);
float a2 = cross(a,b,a,d);
float a3 = cross(c,d,c,a);
float a4 = cross(c,d,c,b);
if (a1*a2 > 0 || a3*a4 > 0)
return -1; //无交点
if (a1 == 0) { // 交点为c
copyPoint(res,c);
return 1;
} else if (a2 == 0) { // 交点为d
copyPoint(res,d);
return 1;
}
//中间交点
float t = a1 / (a1 - a2); // 面积1与面积2异号 保持a1方向
res[0] = c[0] + t*(d[0] - c[0]);
res[1] = c[1] + t*(d[1] - c[1]);
return 1;
}