2016-02-14 7 views
1

У меня есть вопрос относительно тетраэдров - пересечению лучей:Реализация тетраэдров - тест на пересечение луча

Я попытался осуществить тест тетраэдров-лучевого пересечение, который должен возвращать индекс выходного торца. Для пересечения, я следовал за этот блог, где скалярные тройные продукты были использованы для тестирования пересечения:

http://realtimecollisiondetection.net/blog/?p=13

Однако мой код всегда возвращает то же лицо, как выходная грань. После попытки найти решение самостоятельно без успеха, я был бы очень признателен за любые подсказки, где ошибка в моем испытании пересечения могла бы лежать.

Входные параметры - это начало и направление луча, узлы, индексы граней, индексы соседних тетраэдров и индекс последней грани. Показатели выходной поверхности и выходных тетраэдров являются выходными значениями. ScTP вычисляет скалярное трехмерное произведение, а однозначные проверки знака трех поплавков одинаковы. Вот код, спасибо за помощь:

__device__ void GetExitTet(float4 ray_o, float4 ray_d, float4* nodes, int32_t findex[4], int32_t adjtet[4], int32_t lface, int32_t &face, int32_t &tet) 
{ 
face = 0; 
tet = 0; 
float4 q = ray_d; 

    float4 v0 = make_float4(nodes[0].x, nodes[0].y, nodes[0].z, 0); // A 
    float4 v1 = make_float4(nodes[1].x, nodes[1].y, nodes[1].z, 0); // B 
    float4 v2 = make_float4(nodes[2].x, nodes[2].y, nodes[2].z, 0); // C 
    float4 v3 = make_float4(nodes[3].x, nodes[3].y, nodes[3].z, 0); // D 

    float4 p0 = v0 - ray_o; 
    float4 p1 = v1 - ray_o; 
    float4 p2 = v2 - ray_o; 
    float4 p3 = v3 - ray_o; 

    float u_3 = ScTP(q, p0, p1); 
    float v_3 = ScTP(q, p1, p2); 
    float w_3 = ScTP(q, p2, p0); 

    float u_2 = ScTP(q, p1, p0); 
    float v_2 = ScTP(q, p0, p3); 
    float w_2 = ScTP(q, p3, p1); 

    float u_1 = ScTP(q, p2, p3); 
    float v_1 = ScTP(q, p3, p0); 
    float w_1 = ScTP(q, p0, p2); 

    float u_0 = ScTP(q, p3, p2); 
    float v_0 = ScTP(q, p2, p1); 
    float w_0 = ScTP(q, p1, p3); 

    // ABC 
    if (lface != findex[3]) { if (sameSign(u_3, v_3, w_3)) { face = findex[3]; tet = adjtet[3]; } } 
    // BAD 
    if (lface != findex[2]) { if (sameSign(u_2, v_2, w_2)) { face = findex[2]; tet = adjtet[2]; } } 
    // CDA 
    if (lface != findex[1]) { if (sameSign(u_1, v_1, w_1)) { face = findex[1]; tet = adjtet[1]; } } 
    // DCB 
    if (lface != findex[0]) { if (sameSign(u_0, v_0, w_0)) { face = findex[0]; tet = adjtet[0]; } } 
    // No face hit 
    // if (face == 0 && tet == 0) { printf("Error! No exit tet found. \n"); } 
} 

ответ

1

Итак, я придумал решение самостоятельно, в случае, если кто нуждается в этом, вот это:

__device__ void GetExitTet(float4 ray_o, float4 ray_d, float4* nodes, int32_t findex[4], int32_t adjtet[4], int32_t lface, int32_t &face, int32_t &tet) 
{ 
    face = 0; 
    tet = 0; 

    // http://realtimecollisiondetection.net/blog/?p=13 

    // translate Ray to origin and vertices same as ray 
    float4 q = ray_d; 

    float4 v0 = make_float4(nodes[0].x, nodes[0].y, nodes[0].z, 0); // A 
    float4 v1 = make_float4(nodes[1].x, nodes[1].y, nodes[1].z, 0); // B 
    float4 v2 = make_float4(nodes[2].x, nodes[2].y, nodes[2].z, 0); // C 
    float4 v3 = make_float4(nodes[3].x, nodes[3].y, nodes[3].z, 0); // D 

    float4 p0 = v0 - ray_o; 
    float4 p1 = v1 - ray_o; 
    float4 p2 = v2 - ray_o; 
    float4 p3 = v3 - ray_o; 

    double QAB = ScTP(q, p0, p1); // A B 
    double QBC = ScTP(q, p1, p2); // B C 
    double QAC = ScTP(q, p0, p2); // A C 
    double QAD = ScTP(q, p0, p3); // A D 
    double QBD = ScTP(q, p1, p3); // B D 
    double QCD = ScTP(q, p2, p3); // C D 

    double sQAB = signf(QAB); // A B 
    double sQBC = signf(QBC); // B C 
    double sQAC = signf(QAC); // A C 
    double sQAD = signf(QAD); // A D 
    double sQBD = signf(QBD); // B D 
    double sQCD = signf(QCD); // C D 

    // ABC 
    if (sQAB != 0 && sQAC !=0 && sQBC != 0) 
    { 
     if (sQAB < 0 && sQAC > 0 && sQBC < 0) { face = findex[3]; tet = adjtet[3]; } // exit face 
    } 
    // BAD 
    if (sQAB != 0 && sQAD != 0 && sQBD != 0) 
    { 
     if (sQAB > 0 && sQAD < 0 && sQBD > 0) { face = findex[2]; tet = adjtet[2]; } // exit face 
    } 
    // CDA 
    if (sQAD != 0 && sQAC != 0 && sQCD != 0) 
    { 
     if (sQAD > 0 && sQAC < 0 && sQCD < 0) { face = findex[1]; tet = adjtet[1]; } // exit face 
    } 
    // DCB 
    if (sQBC != 0 && sQBD != 0 && sQCD != 0) 
    { 
     if (sQBC > 0 && sQBD < 0 && sQCD > 0) { face = findex[0]; tet = adjtet[0]; } // exit face 
    } 
    // No face hit 
    // if (face == 0 && tet == 0) { printf("Error! No exit tet found. \n"); } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^