碰撞检测:判断线段相交

本文乃Siliphen原创,转载请注明出处:http://blog.csdn.net/stevenkylelee

文本demo演示:

在这里插入图片描述

本文介绍的判断线段相交的算法用到2D向量叉乘,
所以先来了解一下:2D向量的叉乘(叉积)

2D叉乘

3D 叉乘:
3D 叉乘的结果是一个 3D 向量,这个向量垂直于参与运算的2个向量的法向量。
3D 叉乘计算公式:( a.y * b.z - b.y * a.z , a.z * b.x - b.z * a.x , a.x * b.y - b.x * a.y )

2D叉乘:
2D 叉乘的结果是一个标量。
2D 叉乘就是把 2D 点看作 3D 的点( z 轴的值为 0 ),套进 3D 叉乘公式进行计算。
例如:有2个2D向量 a , b ,计算叉乘就是:
( a.y * b.z - b.y * 0 , 0 * b.x - b.z * a.x , a.x * b.y - b.x * a.y )= ( 0 , 0 , a.x * b.y - b.x * a.y )
套进3D叉乘公式计算的2D叉乘的结果的 x , y 分量均为 0 ,只有 z 有意义。
所以,标量 z 是 2D 叉乘的结果。

2D 叉乘公式:
设两个 2D 向量 a , b,叉乘公式:a.x * b.y - b.x * a.y

向量 a 叉乘 向量 b 结果的意义:

  • a ,b 向量构成的平行四边形的面积。
  • 方位:以 a 为参考轴,b 相对于 a 的方位。
    结果 > 0 正数 :b 在 a 的左边,a 的逆时针旋转方向。a 逆时针旋转到 b 的角度小于180°。
    结果 < 0 负数 :b 在 a 的右边,a 的顺时针旋转方向。a 顺时针旋转到 b 的角度小于180°。
    结果 = 0 :a 和 b 向量是平行的。

在这里插入图片描述

如上图所示:
向量 a 把空间分为2部分:

  • 左边的空间:逆时针旋转180°范围内的空间。
  • 右边的空间:顺时针旋转180°范围内的空间。

a 叉乘 b 的结果是 > 0 的正数,b 在 a 的左边。
a 叉乘 c , d 的结果是 < 0 的负数,c , d 在 a 的右边。
a 叉乘 a 的结果是0。因为 a 和它自己是平行的。

2D向量叉乘demo演示:在这里插入图片描述

判断线段是否相交:基于2D叉乘

基本思想:

一个线段会把空间分为2部分,以这个线段为分界线,判断是否另一个线段2个端点分别在这个线段分割的2个空间中。
如果2个线段的2个端点都分别在另一个线段分割的2个空间中,那么就认为是相交。

如下图,有线段 a 和 b
在这里插入图片描述

线段 a 把空间分为2部分,浅蓝和浅绿2部分。
b 的2个端点 bp1、bp2 分别在 a 划分出来的2个空间中。
在这里插入图片描述

同样的,线段 b 把空间分为2部分,浅蓝和浅绿2部分。
a 的 2个端点 ap1 , ap2 分别在 b 划分出来的2个空间中。
在这里插入图片描述

如上图所示,
2个线段的2个端点都在另一个线段分割出来的2个空间中,这2个线段相交。

算法描述:

设有2个线段 a , b 。线段 a 的2个端点为:ap1 , ap2 , 线段 b 的 2个端点为:bp1 , bp2 。
条件1:是否 向量 ap1->bp1 、ap1->bp2 分别位于向量 ap1->ap2 的左右2端。
条件2:是否 向量 bp1->ap1 、bp1->ap2 分别位于向量 bp1->bp2 的左右2端。
当条件1和条件2同时满足时,线段 a , b 相交。

判断一个向量之于另一个向量的方位,可以用2D叉乘。

下图演示如何判断 线段 a 的2个端点分别在线段 b 分割出来的2个空间中。
在这里插入图片描述

以 bp2 为起点,拉出3条向量。分别是 v = bp2->bp1 ,v1 = bp2->ap1 , v2 = bp2->ap2
计算:
c1 = v 叉乘 v1
c2 = v 叉乘 v2
如果 c1 , c2 有一个为负数另一个为正数或者为0,那么说明线段a的2端分别在线段b分割的2个空间中。
c1 和 c2 的值相乘,结果为负数说明互为相反符号的数,否者是相同符号。
条件1计算完毕。

条件2的计算示意图如下,计算过程如法炮制条件1。
在这里插入图片描述

本文demo工程下载:

demo 工程是 cocos creator 2.0.8 写的。
可执行文件是一个网页,直接运行 index.htm 即可。

下载地址:
https://download.csdn.net/download/stevenkylelee/10977144

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 线段相交问题是计算几何学中的常见问题,主要目标是确定两个给定线段是否相交。在解决这个问题时,我们可以使用几何知识和数学方法,下面是一种常见的解决方案: 首先,我们可以将每个线段表示为两个端点的坐标。对于线段AB,我们可以表示为A(x1, y1)和B(x2, y2)。同样的,对于线段CD,我们可以表示为C(x3, y3)和D(x4, y4)。 然后,我们可以利用一系列关系来判断线段是否相交。首先,我们可以通过比较两个线段的最小和最大x坐标来判断它们是否在同一平面上。如果线段AB的最小x坐标大于线段CD的最大x坐标,或者线段AB的最大x坐标小于线段CD的最小x坐标,则可以判断它们不会相交。 接下来,我们可以利用向量的叉积来判断两个线段是否共线。我们可以计算向量AB和向量AC的叉积以及向量CD和向量CA的叉积。如果这两个叉积乘积小于0,则可以判断线段AB和线段CD相交。 最后,我们需要考虑一些特殊情况,例如两个线段共线但没有重叠部分的情况,或者两个线段有一个公共端点的情况。这些情况可以通过包含更多的条件来进一步判断。 通过以上的方法,我们可以相对准确地判断两个线段是否相交。这个问题在计算几何学和计算机图形学中有广泛的应用,例如在碰撞检测、路径规划和游戏开发中都可以使用到。 ### 回答2: line-segments-intersect是一个用于确定两个线段是否相交的算法。这个算法的目标是判断给定的两个线段是否存在交点,若存在,则认为两个线段相交,否则认为它们不相交。 这个算法可以通过以下步骤来实现: 1. 首先,我们需要确定每个线段的两个端点的坐标。假设第一个线段的端点分别为A(x1, y1)和B(x2, y2),第二个线段的端点分别为C(x3, y3)和D(x4, y4)。 2. 接下来,我们需要利用线段AB的斜率和CD的斜率来判断它们是否平行。如果两条线段的斜率相等,那么它们是平行的,此时它们不会相交。 3. 如果线段AB和CD不平行,我们进一步判断它们是否相交。我们可以使用线段的方程来计算两条线段的交点。如果两条线段的交点的x坐标和y坐标都在两个线段的范围内,则认为它们相交。 4. 如果以上条件都不满足,则认为两条线段相交。 通过以上步骤,我们可以确定两个线段是否相交。这个算法可以在计算机程序中实现,并可以用于各种应用场景,如计算几何问题、计算路径交叉等。但需要注意的是,线段相交判断需要考虑特殊情况,如端点重合、线段长度为0等,以保证算法的准确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值