在判断线段的相交时我们可以利用向量的叉积。当两条向量在一条直线上时,向量的叉积等于 0 ,即上面的第二种情况,所以判断两条线段相交就分为两种情况讨论:1.向量的叉积不等于 0 ;2.向量的叉积等于 0 。
一.叉积不等于 0
首先:我们要判断点 p3,p4 分布在线段 p1 p2 两边。如下图所示:
① 根据向量的叉积,如果 p1p4 * p1p2 > 0 则表示向量 p1p2 在向量 p1p4 的逆时针方向,根据 p1p2 * p1p3 > 0,可以判断 p1p3 在 p1p2 的逆时针方向。这时就可以判断点p3,p4 在线段 p1p2 的两端。
② 同理,我们可以判断 p1,p2 分布在线段 p3 p4 的两端。
如果同时满足①,② 成立,则这两个线段就相交
//叉积
double mult(Point a, Point b, Point c)
{
return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
//aa, bb为一条线段两端点 cc, dd为另一条线段的两端点 相交返回true, 不相交返回false
bool intersect(Point aa, Point bb, Point cc, Point dd)
{
if ( max(aa.x, bb.x)<min(cc.x, dd.x) )
{
return false;
}
if ( max(aa.y, bb.y)<min(cc.y, dd.y) )
{
return false;
}
if ( max(cc.x, dd.x)<min(aa.x, bb.x) )
{
return false;
}
if ( max(cc.y, dd.y)<min(aa.y, bb.y) )
{
return false;
}
//ac*ab < 0 或者 ab*ad<0
if ( mult(cc, bb, aa)*mult(bb, dd, aa)<0 )
{
return false;
}
//ca*cd<0 或者 cd*cb<0
if ( mult(aa, dd, cc)*mult(dd, bb, cc)<0 )
{
return false;
}
return true;
}