直线或线段与mesh网格相交的计算

引言

在采样二指夹爪与mesh网格的抓取点时使用的点接触模型,抽象二指夹爪为一个线段,那么寻找夹爪与物体的接触点就抽象为直线与mesh网格的交点问题,而在mesh中物体表面是以空间三角形保存的,在进一步的问题及变成如何计算三维坐标下三角形与直线的交点问题。
当然最简单方法是遍历每一个三角形,计算三角形所在平面与直线的交点,然后判断该交点是否在线段上并且在三角形内。
但是以上方法中计算交点消耗大量计算资源,对mesh网格中的成千上万的三角形计算下来效率低下。
所以我打算采用先判断直线与三角形是否有交点的问题,最后再计算交点。
下面计算两种判断直线与网格中的三角形是否有交点的方法,其中第一种是我自己想的,第二种是参考网上资料的。

方法1:在二维平面上判断点是否在三角形内

第一步:判断直线是否与三角形平面平行或在三角形平面内,这一步只需做直线方向向量与三角形法向量的点积即可,不详细叙述。
第二步:把三角形投影到二维平面上,我们可以想象一下把空间中的三角形投影到以已知直线作为法线的平面上,那么直线在平面内的投影就只是一个点,而三角形在该平面上还是一个三角形,要判断直线是否与三角形有交点只需判断投影点与投影三角形之间的关系即可。为了方便起见,在这一步我直接把整个mesh旋转到以所求直线为z轴的坐标上,那么只需求解三角形在xOy平面上的投影与原点之间的关系即可。
第三步:判断平面上点与三角形位置关系,这里我参考了https://www.cnblogs.com/TenosDoIt/p/4024413.html。

用到向量的叉乘。假设三角形的三个点按照顺时针(或者逆时针)顺序是A,B,C。对于某一点P,求出三个向量PA,PB,PC, 然后计算以下三个叉乘(^表示叉乘符号):
t1 = PA^PB,
t2 = PB^PC,
t3 = PC^PA,
如果t1,t2,t3同号(同正或同负),那么P在三角形内部,否则在外部。

方法2:利用Plucker坐标判断三角形与直线位置关系

这里参考到的文章有

https://www.cnblogs.com/flyuz/p/9471031.html
https://members.loria.fr/SLazard/ARC-Visi3D/Pant-project/files/Line_Segment_Triangle.html
https://members.loria.fr/SLazard/ARC-Visi3D/Pant-project/files/Line_Triangle.html

以上的三篇文章中详细介绍了用Plucker坐标判断三角形与直线和线段位置关系的方法。下面我简单介绍一下Plucker坐标的相关知识。

Plucker坐标用来表示由a =(px,py,pz)和b =(qx,qy,qz)组成的直线
L =(L [0],L [1],L [2],L [3],L [4],L [5])
l0 = a[0] * b[1] - b[0] * a[1]
l1 = a[0] * b[2] - b[0] * a[2]
l2 = a[0] - b[0]
l3 = a[1] * b[2] - b[1] * a[2]
l4 = a[2] - b[2]
l5 = b[1] - a[1]

Side Operator是一个对Plucker坐标和的运算:(a,b都是Plucker坐标)
side(a,b) = a[0]*b[4] + a[1]*b[5] + a[2]*b[3] + a[3]*b[2] + a[4]*b[0] + a[5]*b[1]

令:S1 = side-operator(L,e1),S2 = side-operator(L,e2),S3 = side-operator(L,e3)

  1. 直线和三角形不共面且直线穿过三角形:S1, S2, S3 <0 或 S1, S2, S3 >0
    直线或线段与mesh网格相交的计算_第1张图片
  2. 直线和三角形不共面且没有角度的:S1, S2, S2符号不相同
    直线或线段与mesh网格相交的计算_第2张图片
  3. 直线和三角形不共面且直线穿过一个顶点:S1, S2, S2 中两个为0
    直线或线段与mesh网格相交的计算_第3张图片
  4. 直线和三角形不共面且直线穿过一条边:S1, S2, S2 中一个为0且另外两个符号相同
    直线或线段与mesh网格相交的计算_第4张图片

其他的直线和三角形共面的情况具体参见以上的参考网站

你可能感兴趣的:(Dex-Net学习)