삼각형과 삼각형의 충돌 검사

3차원 공간에서 두 삼각형의 충돌 검사는 매우 중요한 문제로, **Separating Axis Theorem (분리축 정리, SAT)**를 기반으로 수행하는 것이 일반적이다. 이 방법은 두 물체가 충돌하지 않으면 이들을 분리하는 축이 반드시 존재한다는 사실에 기반한다. 즉, 분리축이 하나라도 존재하면 두 삼각형은 충돌하지 않으며, 그렇지 않으면 충돌이 발생한 것이다.

삼각형 정의

두 삼각형 $T_1$과 $T_2$는 각각 3개의 꼭짓점으로 정의된다:

  • 삼각형 $T_1$: $\mathbf{v}{1a}, \mathbf{v}{1b}, \mathbf{v}_{1c}$

  • 삼각형 $T_2$: $\mathbf{v}{2a}, \mathbf{v}{2b}, \mathbf{v}_{2c}$

분리축 후보

충돌 여부를 확인하기 위해 아래의 여러 분리축을 검토한다:

  1. 각 삼각형의 법선 벡터 (Plane Normal Vectors) 삼각형들이 서로 다른 평면에 있을 때, 그 평면 간의 충돌 여부를 확인하기 위해 각 삼각형의 법선 벡터를 이용한다. 각 삼각형의 법선 벡터는 해당 평면의 수직 벡터이다:

    • 삼각형 $T_1$의 법선 벡터:

n1=(v1bv1a)×(v1cv1a) \mathbf{n}_1 = (\mathbf{v}_{1b} - \mathbf{v}_{1a}) \times (\mathbf{v}_{1c} - \mathbf{v}_{1a})
  • 삼각형 $T_2$의 법선 벡터:

n2=(v2bv2a)×(v2cv2a) \mathbf{n}_2 = (\mathbf{v}_{2b} - \mathbf{v}_{2a}) \times (\mathbf{v}_{2c} - \mathbf{v}_{2a})
  1. 두 삼각형의 변 벡터와 서로의 변 벡터의 외적 삼각형 간의 변들이 교차하는지를 확인하기 위해, 각 삼각형의 변과 다른 삼각형의 변 벡터의 외적을 분리축으로 사용한다. 이 외적 벡터들이 충돌을 감지할 수 있는 분리축을 제공한다:

nedge=(v1iv1j)×(v2kv2l)\mathbf{n}_{edge} = (\mathbf{v}_{1i} - \mathbf{v}_{1j}) \times (\mathbf{v}_{2k} - \mathbf{v}_{2l})

여기서 $i, j, k, l \in {a, b, c}$는 삼각형의 변을 의미한다.

분리축에서의 투영

각 분리축에 대해 두 삼각형의 꼭짓점을 투영한 후, 그 투영 범위가 겹치는지를 확인한다:

  • 삼각형 $T_1$의 투영 범위: 각 꼭짓점 $\mathbf{v}{1a}, \mathbf{v}{1b}, \mathbf{v}_{1c}$을 분리축 $\mathbf{n}$에 대해 투영하여 최소값과 최대값을 계산한다:

p1i=v1in,(i = a, b, c)p_{1i} = \mathbf{v}_{1i} \cdot \mathbf{n}, \quad \text{(i = a, b, c)}

투영된 값 중 최소값과 최대값을 계산하여 해당 축에서의 투영 범위를 얻는다.

  • 삼각형 $T_2$에 대해서도 동일한 방식으로 투영을 수행하고 투영 범위를 계산한다.

충돌 여부 판단

모든 분리축에 대해 두 삼각형의 투영 범위가 겹치지 않는 분리축이 하나라도 존재한다면, 두 삼각형은 충돌하지 않는다. 하지만 모든 분리축에서 투영 범위가 겹치면 두 삼각형은 충돌한 것이다.

추가 고려 사항

특수한 경우에 대해 다음과 같은 추가 검사를 할 수 있다:

  1. 삼각형이 같은 평면에 있는 경우: 두 삼각형이 동일한 평면에 위치하는 경우, 법선 벡터의 방향이 동일해질 수 있다. 이 경우에는 법선 벡터를 사용한 분리축 검사가 효과적이지 않으므로, 평면 내부에서의 교차 여부를 확인해야 한다. 이를 위해 삼각형 간의 꼭짓점이 다른 삼각형의 내부에 포함되는지, 혹은 두 삼각형의 변이 서로 교차하는지를 추가로 검사해야 한다.

  2. 삼각형의 꼭짓점이 다른 삼각형의 내부에 있는 경우: 한 삼각형의 꼭짓점이 다른 삼각형 내부에 위치하는 경우, 이는 충돌로 간주된다. 이를 확인하려면 각 삼각형의 꼭짓점이 다른 삼각형의 면적 내에 포함되는지를 검사할 수 있다.

C++ 구현

두 삼각형 간의 충돌 검사를 C++와 Eigen 라이브러리를 사용하여 구현하는 방법을 소개하겠다. 여기에서는 **Separating Axis Theorem (SAT)**을 이용한 충돌 검사를 수행하며, Eigen을 사용하여 벡터 연산을 처리한다.

주요 설명:

  1. computeNormal 함수: 삼각형의 법선 벡터를 계산한다. 이 법선 벡터는 분리축으로 사용된다.

  2. projectOntoAxis 함수: 삼각형의 꼭짓점들을 분리축에 투영하여 최소 및 최대 값을 계산한다.

  3. isOverlapping 함수: 분리축에서 두 삼각형의 투영이 겹치는지 확인한다.

  4. checkTriangleCollision 함수: 각 분리축에서 충돌 여부를 검사한다. 법선 벡터뿐만 아니라 변의 외적을 분리축으로 사용하여 교차 여부를 확인한다.

Last updated