Real time Randering 2nd에서 참고했습니다.
이론을 간단히 설명하자만 점이 폴리곤 내부에 있다면 점과 각 점점을 이루는 내각의 합이 360이라는겁니다.
예를들면 세 정점 p1, p2, p3로 이루어진 폴리곤이 있을때 정점p와의 각도를 계산합니다.
1. p1-p와 p2-p의 벡터가 이루는 각
2. p2-p와 p3-p의 벡터가 이루는 각
3. p3-p와 p1-p의 벡터가 이루는 각
자 그런데 각도는 어떻게 계산하느냐?? 그건 벡터의 성질을 이용하면 간답합니다.
1번 상황에서 p1-p간의 벡터를 A라하고 p2-p간의 벡터를 B라 할 때...
두 벡터의 크기를 곱합니다.
그리고 그 크기가 0이 아니라면..(이때 진짜 0을 비교하시면 안됩니다.
부동소수점 정밀도 문제때문에 0.000001같이 정당한 작은 값을 비교해서 그 값보다 작으면 0이라고 가정하는겁니다.
아무튼.. 두 벡터의 크기가 0보다 크다면...
이렇게 계산됩니다. 실제 구현한 코드는 밑에 접어놨어요~^^
bool CxWall::CollisionTriangle(CVector& p1, CVector& p2, CVector& p3, CVector& p)
{
const double eps = 0.000001;
double length, angle, temp;
CVector A, B, C;
angle = 0.0;
A = p1 - p;
B = p2 - p;
length = A.Length() * B.Length();
if (length > eps)
{
temp = A.Dot(B);
angle += (double)acos( temp / length );
}
else
length = 360.0;
A = p2 - p;
B = p3 - p;
length = A.Length() * B.Length();
if (length > eps)
angle += (double)acos( A.Dot(B) / length );
else
length = 360.0;
A = p3 - p;
B = p1 - p;
length = A.Length() * B.Length();
if (length > eps)
angle += (double)acos( A.Dot(B) / length );
else
length = 360.0;
if ( angle >= (0.99 * (2.0 * 3.14159)) )
return true;
return false;
}