2014-12-27 4 views
1

현재 경로 추적기를 작성 중입니다. 이제 광선 - 삼각형 교차를 구현하고 싶습니다. 그래서 내 삼각형은 세 개의 점 (v0, v1, v2)으로 구성됩니다. 이 주제에 대한 다른 게시물 (Raytracing - Ray/Triangle Intersection)을 보았습니다. 슬프게도 제대로 작동하지 않기 때문에 문제가 교차로에 있는지 확인하고 싶습니다. 다음은 두 개의 삼각형 함수입니다.Pathtracing 레이 삼각형 교차점

public float intersect(Ray ray){ 
    Vector3D e1 = v1.sub(v0); 
    Vector3D e2 = v2.sub(v0); 
    Vector3D e1e2 = e1.cross(e2).normalize(); 

    Vector3D p = ray.direction.cross(e2); 

    float a = e1.dot(p); 
    if(a < 0.0) 
     return -1.0f; 

    float f = 1.0f/a; 
    Vector3D s = ray.origin.sub(v0); 
    float u = f*(s.dot(p)); 
    if(u < 0.0 || u > 1.0) 
     return -1.0f; //no hit 

    Vector3D q = s.cross(e1); 
    float v = f * (ray.direction.dot(q)); 
    if(v < 0.0 || v > 1.0) 
     return -1.0f; //no hit 

    float t = f * (e2.dot(q)); //distance 
    return t; 
} 

public Vector3D normal(Vector3D nVec){ 
    Vector3D e1 = v1.sub(v0); 
    Vector3D e2 = v2.sub(v0); 
    Vector3D e1e2 = e1.cross(e2).normalize(); 
    return e1e2; 
} 

이 코드가 맞습니까?

답변

1

매우 정교하게 설명하는 이름을 사용하지 않으므로 정직하게 읽는 것이 어렵습니다. 내가 의사에 무엇을했는지를 주겠다 :

//1.Find intersection point of the ray and the infinite Plane created by triangle, 
//or find if the ray is parralel to the plane (no intersection Point) 
//2.Find out if the intersection point is within the triangle itself 

Triangle: Vector A, Vector B, Vector C 
ray: Vector rayOrig, Vector rayDir 
Intersection: boolean hasHit = false, Vector hitPoint, float t 

Vector normal = (B-A)CrossProduct(C-A) //I think you had basically the same with e1e2 
float d = (normal)DotProduct(A) 
float nd = (normal)DotProduct(rayDir) 
if(nd!=0) 
{ //The ray hits the triangles plane 
    Intersection.t=(d- (normal).DotProduct(rayOrig))/nd 
    Intersection.hitPoint=rayOrig+(rayDir*Intersection.t) 
    if (pointInTriangle(Intersection.hitPoint, A, B, C)) 
    { 
     Intersection.hasHit = true 
    } 
} 
return Intersection 

공지 사항을 비행기로 교차점을받은 후 삼각형의 기능 점수는 부울을 반환해야하는 호출됩니다. 나는으로부터 내 방법을 가지고 : 당신이이 부분에서 비슷한 일을하고있는 것 같습니다, 두 번째 무게 중심 coordiantes를 사용 http://www.blackpawn.com/texts/pointinpoly/

if(u < 0.0 || u > 1.0) 
    return -1.0f; //no hit 

Vector3D q = s.cross(e1); 
float v = f * (ray.direction.dot(q)); 
if(v < 0.0 || v > 1.0) 
    return -1.0f; //no hit 

전혀하지만 레이 평면 교차 확인하는 것은 당신이 봐 나던 그것을 다른 기능으로하고 있습니까? 그렇다면 삼각형 테스트를 위해 광선 방향이 실제로 필요하다고 생각하지 않습니다.

1

구현 한 알고리즘은 유명한 Möller-Trumbore 교차 알고리즘입니다. 코드가 정확합니다. 코드가 일부 코드를 감지하지 못하면 백 오더 컬링을 검사하기 때문일 수 있습니다. 첫 번째 테스트를 if (a == 0.0f)으로 변경하여 해당 테스트를 제거 할 수 있습니다.

또한 4 줄의 Vector3D e1e2 = e1.cross(e2).normalize();에 삼각형 평면의 법선 벡터를 계산하지 않아도됩니다.