平面内线段相交判断
说到线段, 我们很自然想到直线,判断两条直线是否相交只需判断它们斜率是否相等,相等就为平行或重合, 不等就相交(注:判断相交我们不采用除法,因为除法容易产生浮点误差,当两条直线斜率接近时,很容易出错。 事实上,几乎所有几何题都不建议采用除法)。
线段相交有两种形式:
规范相交和 非规范相交 。 区别就是交点是否是其中一条线段的端点,不是的是规范相交。
叉积的概念: 设向量 a(x1, y1) 、 b(x2, y2) ;
a x b = x1*y2 - x2*y1; (与数学中的叉积不太一样)
判断线段相交比较繁琐,主要就是判断异侧:
我们以一条线段的一端点为起点,沿着线段方向看去(一条射线),在左手边为逆时针方向,右手边为顺时针方向。如果另一线段两端点分别在这一线段的两侧,那么线段可能相交(也可能在线段外),否则不可能相交。对另一线段采用相同方法就可判断出是否相交了。
这个过程主要通过叉积来判断: 叉积大于 0 ,在点在向量的顺时针方向,小于 0 , 在逆时针方向 ; 等于 0, 端点在直线上。
具体实现:
设:线段 a :P1(x1, y1)、P2(x2, y2) 线段 b: Q1(x3, y3)、Q2(x4, y4)
d1 ====> (P2 - P1) x (Q1 - P1) (叉积)
d2 ====> (P2 - P1) x (Q2 - P1) (叉积)
d3 ====> (Q2 - Q1) x (P1 - Q1) (叉积)
d4 ====> (Q2 - Q1) x (P2 - P1) (叉积)
首先,先判断端点是否在另一线段上。
然后,我们只需判断 d1 * d2 < 0 并且 d3 * d4 < 0 便可判断线段相交。
java实现代码:
public static boolean isIntersect(Gps gps1, Gps gps2, Gps gps3, Gps gps4){
double d1 = ((gps1.getWgLon() - gps2.getWgLon()) * (gps3.getWgLat() - gps1.getWgLat())) - ((gps2.getWgLat() - gps1.getWgLat()) * (gps3.getWgLon() - gps1.getWgLon()));
double d2 = ((gps1.getWgLon() - gps2.getWgLon()) * (gps4.getWgLat() - gps1.getWgLat())) - ((gps2.getWgLat() - gps1.getWgLat()) * (gps4.getWgLon() - gps1.getWgLon()));
double d3 = ((gps3.getWgLon() - gps4.getWgLon()) * (gps1.getWgLat() - gps3.getWgLat())) - ((gps3.getWgLat() - gps4.getWgLat()) * (gps1.getWgLon() - gps3.getWgLon()));
double d4 = ((gps3.getWgLon() - gps4.getWgLon()) * (gps2.getWgLat() - gps3.getWgLat())) - ((gps3.getWgLat() - gps4.getWgLat()) * (gps2.getWgLon() - gps3.getWgLon()));
if(d1 * d2 <= 0 && d3 * d4 <= 0){
return true;
}
return false;
}