java 平面内线段相交判断

平面内线段相交判断

  说到线段, 我们很自然想到直线,判断两条直线是否相交只需判断它们斜率是否相等,相等就为平行或重合, 不等就相交(注:判断相交我们不采用除法,因为除法容易产生浮点误差,当两条直线斜率接近时,很容易出错。 事实上,几乎所有几何题都不建议采用除法)。

  线段相交有两种形式:

    规范相交和 非规范相交 。 区别就是交点是否是其中一条线段的端点,不是的是规范相交。

  叉积的概念: 设向量 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;
    }

理论出处

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值