2012-01-17 3 views
0

그래서 나는 또 다른 광선 추적 질문으로 돌아 왔습니다. 내 코드는 모든 영역을 훌륭하게 멋지게 표현하지만 큐브는 실제로 작동하지 않습니다. 내가 카메라가 있음을 확인했습니다광선 추적 상자 교차점

Cube* c1 = new Cube;  
c1->Corner1 = Vec3(100, 100, 100);  
c1->Corner2 = Vec3(200, 200, 200); 

: 나는 교차로를 테스트하기 위해이 코드를 사용하고 있습니다 :로 http://pastebin.com/qgm6vpdx은 (그것은, t는 교차점까지의 거리 재귀 함수입니다 것) 경계 상자가 정의됩니다 큐브 안쪽. 유일한 문제는 전체 화면이 녹색 (큐브에 지정된 색)으로 표시된다는 것입니다.

저는 큐브 교차점을 올바르게하고 있다고 생각하지 않습니다. 누구든지 내 코드를 읽을 수 있습니까?

+0

안녕하세요 Chris는 게시자가 도움을 요청하지 않도록하고 싶지 않지만 질문하기 전에 코드에 대한 온 전성 검사를 수행해야한다고 생각합니다. 예를 들어 상자 교차가 작동하지 않는 경우 테스트 상황에서 정답이 무엇인지 알 수 있습니다. 즉, (1,0,0)을 따라 이동하는 (1,0,0,0.5)의 광선과 교차하는 크기 (1,1,1)의 (0,0,0)에있는 모서리가있는 상자는 (0,0.5) , 0.5), 이런 종류의 일. 그런 다음 여기에 올 때 단지 증거 읽기 서비스로 사용하지 않고 조언을 얻을 수 있습니다. –

답변

3

코드를 더 짧고 가독성있게 만들 수 있습니다. 예를 들어,

if(t1 > t2) 
{ 
    float temp1 = t1; 
    t1 = t2; 
    t2 = temp1; 
} 

if(t1 > t2) 
{ 
    // std::swap is built-in 
    swap(t1, t2); 
} 

이상

// Define 'order' yourself 
order(t1, t2); 

하고

if(t1 > tNear) 
{ 
    tNear = t1; 
} 

을 변경 int tNear = INT_MINint tNear = -2147000000을 변경하고 변경

if ((ray.dir.x == 0) && (ray.start.x < Min.x) && (ray.start.x > Max.x)) 
{ 
    //parallel 
    return false; 
} 
else 
{ 
    float t1 = (Min.x - ray.start.x)/ray.dir.x; 
    float t2 = (Max.x - ray.start.x)/ray.dir.x; 
    order(t1, t2); 
    tNear = max(tNear, t1); 
    tFar = max(tFar, t1); 
    if ((tNear > tFar) || (tFar < 0)) 
     return false; 
} 

을 그리고 이것은 하나의 문제를 보여준다 :

// std::max is built in 
tNear = max(tNear, t1); 

그런 다음 코드의 한 부분이된다. tNeartFar은 라인이 큐브와 교차하는 간격 인 t 값을 정의합니다. 테스트하는 각 좌표 (x, y 및 z)는 간격을 더 제한합니다. 그러나 코드 tFar = max(tFar, t1)이 간격을 확장하고 있습니다. 그것을 tFar = min(tFar, t1)으로 변경하십시오.

근본적으로, 이것은 축 정렬 입방 형으로 제한됩니다. 그러나이 코드는 나중에 더 복잡한 모양에 대한 빠른 히트 테스트로 유용 할 수 있습니다. 어쨌든, 일단 이것이 작동하면 좀 더 일반적인 것으로 만들 수 있습니다.

모든 볼록 다각형을 법선이 바깥 쪽을 향하게하여 무한 평면 세트로 정의 할 수 있습니다. 모든면의 "내부"에있는 점은 다각형 내부에 있습니다.

평면은 공간을 두 개의 절반으로 나눕니다. 정상 점이 "외부"이고 다른 반쪽이 "내부"인 반을 정의하십시오. 그러면 그 점에서 평면 방정식이 양수이면 점이 평면 외부에 있고, 값이 음수이면 평면 내부에, 값이 0 인 경우 평면에 점이 있습니다.

이것을 광선 추적하려면 광선/평면 교차를 결정하고 가장 가까운 것을 선택하십시오. 포인트가 얼굴 안에 있는지 확인하려면 (비행기가 무한하다는 것을 기억하십시오) 포인트가 다른 모든 비행기 안에 있는지 확인하십시오. 그렇지 않은 경우 가장 가까운 다음 교차로를 테스트하는 등의 작업을 수행합니다.

일단 이것이 작동하면 일반 교차로 및 모양의 차이 (예 :면 중 하나에서 반구형 들여 쓰기가있는 입방체)로이를 쉽게 확장 할 수 있습니다.

5

레이 박스 교차를 계산하는 데 가장 적합한 알고리즘 중 하나는 slab method입니다.필자는 최적화 된 구현 인 here에 대해서도 설명했습니다.

+0

이미 사이트에서 내 방법을 얻었지만 어쨌든 고마워요. – Chris

+0

안녕하세요 Tavian,이게 매우 유용하다는 걸 알았습니다! - 그러나,이 방법은 방향 벡터의 부호를 존중/이해하기로되어 있습니까? Golang에 대한 함수의 행 단위 복사가 보이지 않기 때문에 - 여기에 SO 질문을 제기했습니다. http://stackoverflow.com/questions/9971105/slab-method-for-ray-box- 교차점 - 반대 - 긍정 - 반대 - 방향성을 제공 – metaleap