MathJax

2012년 4월 14일 토요일

광선과 평면 교차 ( Intersecting segment(ray) and plane )



선분 ab는 다음의 식으로 표현할 수 있다.
s(t) = a+ t (b - a
a는 선분의 시작점(org)을 나타내다.
(b - a)는 선분의 방향(dir)을 나타내고 크기는 1이 된다.
그리고 t는 선분 상의 위치를 나타내는 변수고, 0 이상 1이하의 값을 가지게 된다.

여기서 
t 값이 +. -  방향 모두 무한대가 되면 직선, 
t 값이 한쪽 방향으로만 무한대가 되면 반직선이 된다. 
평면과 교차할때 직선의 t 값을  알아내면  교차점을 알아낼 수 있다.

평면의 식을 다음과 같이 나타내고 
n x + d = 0

특정 t 값 일때의 선분을 위 식에 대입한다.
n ( a+ t (b - a))  + d = 0

식을 t 에 대하여 정리하게 되면 아래과 같이 된다.

t = ( -n a - d ) / ( n(b - a))

계산한 결과 t 값이 0 이상 1 이하라면 해당 평면과 선분을 교차하게 된다.

반직선의 경우는 검사하는 t 값을 범위를 조절하면 
평면과 반직선의 교차 여부를 판단할 수 있다.
~/Documents/segment_plane.cpp.html
-->
 1 bool segment_plane(vector3& org, vector3& dir, plane& p,
 2                 vector3& out_res)
 3 {
 4         float t = (-vec3_dot(p.normal, org) - p.d) /
 5                         vec3_dot(p.normal, dir);
 6 
 7         if(t >= 0.0f && t <= 1.0f)
 8         {
 9                 out_res = org + t * dir;
10                 return true;
11         }
12         return false;
13 }

참고문헌:
Real-Time Rendering 2판
Real-Time Collision Detection

2012년 4월 1일 일요일

AABB와 구 교차 ( Intersecting AABB and sphere )


AABB의 점들 중에서 구의 중심과 거리가 가장 가까운 점을
찾아서 충돌 확인한다.


AABB이므로 각 축별로 구의 중심과 거리를 확인한다.

구의 중심이 v_min과 v_max 사이에 있을 경우는 서로 교차하므로
따로 검사가 필요 없다.

-->
bool CollisionSphereAABB(Sphere& s, AABB& aabb) {
        float dist = 0.0f;

        for(int i=0; i<3; i++)
        {
                if( s.center[i] < aabb.v_min[i] )
                {
                        d += ((aabb.v_min[i] - s.center[i]) *
                                (aabb.v_min[i] - s.center[i]));
                }
                else if( s.center[i] > aabb.v_max[i] )
                {
                        d += ((s.center - aabb.v_max[i]) *
                                (s.center - aabb.v_max[i]));
                }
        }

        if( dist > s.center * s.center )
                return false;

        return true;
}


참고 문헌
Real-Time Rendering 2판
Real-Time Collision Detection