在DeepSDF论文复现1—数据集生成2—原理解析 这篇文章中,我们发现ShapeNet数据集中的数据是按照不同模块构建的,因为模块之间的重叠,有些三角形一部分在三维体内部一部则在外部,从而导致我们提取的三维体表面不太干净(不干净的程度取决于三角形在三维体内部的那部分的大小)。这篇文章我们将研究空间中三角形对的相交判断与交点计算方法,为解决这个问题提供工具。
三角形对相交判断与交点计算是一个经典的计算几何问题,有很多相关的研究。博主选的是《A Fast Triangle-Triangle Intersection Test》这篇文章讲述的方法进行实现。需要注意的是,该算法即不是最新的也不是最快的,选它是因为其比较好理解,加之我们的需求对时间不是特别敏感。
A Fast Triangle-Triangle Intersection Test原理解析
文章的思路非常简单,对于空间中的两个三角形,要定义其是否相交,可以分为两步走:
-
判断一个三角形的三个顶点是否在另外一个三角形所在表面的一侧,如果是的话它们不相交。如果不是,那么就可能是共面或者相交。因为研究的是相交,因此共面的情况直接返回,判断剩下情况是否相交即可。
-
因为前面已经保证了两个三角形所在的平面一定是相交的,因此只需要求出交线,然后判断在三角形内部的交线是否重叠即可。重叠为相交,否则不相交。两种情况如下图1所示。

当然,要实现上述两个步骤的计算并没有想象中的那么容易。下面讲一下文章的思路。
定义两个三角形为 T 1 T_1 T1和 T 2 T_2 T2,其顶点分别为 V 0 1 , V 1 1 , V 2 1 V_0^1,V_1^1,V_2^1 V01,V11,V21和 V 0 2 , V 1 2 , V 2 2 V_0^2,V_1^2,V_2^2 V02,V12,V22,所在的平面为 π 1 \pi_1 π1和 π 2 \pi_2 π2,法线为 N 1 N_1 N1和 N 2 N_2 N2。
因为通常只知道三角形的顶点坐标,因此第一步就需要先用顶点坐标来描述其他对象。以第二个三角形为例,其法线为:
N 2 = ( V 1 2 − V 0 2 ) × ( V 2 2 − V 0 2 ) N_2=(V_1^2-V_0^2)\times(V_2^2-V_0^2) N2=(V12−V02)×(V22−V02)
因为平面方程的表达式为: a x + b y + c z = d ax+by+cz=d ax+by+cz=d,其中 a , b , c a, b, c a,b,c是法向量的分量(即 N = ( a , b , c ) N=(a,b,c) N=(a,b,c)),因此要求 π 2 \pi_2 π2只需要再求一个 d 2 d_2 d2即可。
又因为三角形的顶点肯定是平面上的点,因此 d 2 = − N 2 ⋅ V 0 2 d_2=-N_2\cdot V_0^2 d2=−N2⋅V02。即 π 2 \pi_2 π2的表达式为:
N 2 ⋅ X + d 2 = 0 N_2\cdot X+d_2=0 N2⋅X+d2=0 N 2 ⋅ X − N 2 ⋅ V 0 2 = 0 N_2\cdot X-N_2\cdot V_0^2=0 N2⋅X−N2⋅V02=0 N 2 ⋅ ( X − V 0 2 ) = 0 N_2\cdot (X-V_0^2)=0 N2⋅(X−V02)=0
要求 T 1 T_1 T1的三个顶点是否在此 π 2 \pi_2 π2的一侧,求 V 0 1 , V 1 1 , V 2 1 V_0^1,V_1^1,V_2^1 V01,V11,V21到 π 2 \pi_2 π2即可:
d V i 1 = N 2 ⋅ ( V i 1 − V 0 2 ) , i = 0 , 1 , 2 d_{V_i^1}=N_2\cdot (V_i^1-V_0^2), i=0,1,2 dVi1=N2⋅(Vi1−V02),i=0,1,2
如果 d V i 1 ≠ 0 d_{V_i^1}\neq 0 dVi1=0且三个值同号,则说明 T 1 T_1 T1位于 π 2 \pi_2 π2的一侧,两个三角形不相交。
如果三个值都为0,则两个三角形同面,通常情况下知道这个信息即可。如果需要进一步求两个三角形是否有重叠区域,可以通过求线段交点实现。
如果其中有一个 d d d为 0 0 0,剩下两个 d d d同号,则证明 T 1 T_1 T1刚好有一个点位于 π 2 \pi_2 π2上(不一定位于 T 2 T_2 T2三角形中),这种情况可认为两个三角形不相交。
剩下的三种情况 π 1 \pi_1 π1和 π 2 \pi_2 π2都是相交于一条线的,只要求穿过两个三角形的交线是否有重叠则可直接判断三角形是否相交:
- 两个 d d d为 0 0 0,剩下的 d d d不为0。则连接两个 d d d为 0 0 0的顶点的边为相交的线段。
- 有一个 d d d为 0 0 0,剩下两个 d d d不为0且异号。d为0的顶点为相交线段的一个端点,只需要求出另外一个端点即可。
- 三个 d d d都不为 0 0 0且其中一个 d d d和另外两个 d d d不同号。此时需要求出两个端点位置
后两种情况需要知道怎么去计算线段的端点。
设交线方程为 L = O + t D L=O+tD L=O+tD,其中 O O O是线上的一点, D D D是线的方向,因为该线同时在 π 1 \pi_1 π1和 π 2 \pi_2 π2上,即同时垂直于法线 N 1 N_1 N1和 N 2 N_2 N2,因此 D = N 1 × N 2 D=N_1\times N_2 D=N

4395

被折叠的 条评论
为什么被折叠?



