碰撞检测第二重奏——胶囊体碰撞检测

来源:互联网 发布:java解析soap报文 编辑:程序博客网 时间:2024/05/01 11:37

胶囊体:给定一条线段L,所有道L的距离为r的点的集合。

由定义可知,胶囊体由半径r和线段L标识。检测两个胶囊体是否发生碰撞,即检测两条线段L1、L2的最短距离d是否大于L1、L2的半径r1、r2之和,d  > r1 + r2 ,则未碰撞,否则发生碰撞。


求得L1、L2的最短距离

设线段L1端点为a1、a2,线段L2端点为b1、b2,“ * ”号表示两向量做叉积。

1、如果线段L1、L2共线,直接比较端点距离,得到最小值。

判断共线条件:向量  a1a2 * b1b2 = 0,a1a2  *  a1b1 = 0   (四个点任意组合成两个向量,都平行)

2、如果L1、L2共面(不共线),取L1的中点c1,并做垂线垂直于L2,垂足为c1,保留c1、c2;

因为c1、c2不一定存在于线段L1、L2上,此时最短距离d有9种可能(见下面伪代码)

  If c1<a1

      If c2<b1, 则d=|c1b1|;

      else if b2<c2, 则d=|a1b2|;

      else  d=|a1c2|;

  else if a2<c1

      if c2<b1, 则 d=|a2b1|;

      else if b2<c2, 则d=|a2b2|;

      else  d=|a2c2|;

  else

      if c2<b1, 则d=|c1b1|;

      else if b2<c2, 则d=|c1b2|;

      else  d=|c1c2|;

判断共面条件:a1a2  *  b1b2  =  0 (即两个向量平行)

3、如果L1、L2异面,求出共垂线与L1、L2的交点c1、c2

http://blog.sina.com.cn/s/blog_648868460100h1sf.html  空间中两异面直线共垂线及其交点求解过程

为了方便编程,我用向量进行求解:

L1、L2的方向向量v1、v2(即向量a1a2、b1b2单位化)作叉积得到共垂线方向向量v3 = v1 * v2,

v1、v3作叉积得到L1与共垂线组成的平面的法向量 n = v1 * v3 ,平面方程为  n * (x , y , z) + q = 0

q = -( n * (x , y , z))

令 k = (n * b1 + Q) /  (n * b0b1)

L1与共垂线交点 c1 = k * q + b0 ,

用同样的方法可求得L2与共垂线的交点 c2.


同共面(不共线)的情况,因为上述求共垂线交点是基于L1、L2是直线,而我们实际情况是L1、L2是线段,c1、c2不一定位于线段L1、L2上,此时最短距离同样是9中情况,判断方法与共面(不共线)的情况相同。


到此,只需要比较最短距离d与两个胶囊体半径r1、r2的大小即可判断两胶囊体是否碰撞。


0 0
原创粉丝点击