2012-01-17 9 views
0

Итак, я вернулся с другим вопросом о трассировке лучей. Мой код делает сферы прекрасными и денди, но кубы на самом деле не работают. Я использую этот код для проверки пересечений: http://pastebin.com/qgm6vpdx (Это рекурсивная функция, т расстояние до точки пересечения) Габаритный прямоугольник определяется как:Перекрестки перекрестных лучей Ray

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

Я подтвердил, что камера не внутри куба. Теперь единственная проблема заключается в том, что весь экран отображается зеленым (цвет, обозначенный на кубе)

Я не думаю, что я делаю пересечения кубов вправо, может ли кто-нибудь подтвердить мой код?

+0

Привет, Крис, я не хочу препятствовать вам размещать и получать помощь, но я думаю, вы должны выполнить некоторые проверки здравомыслия в своем коде, прежде чем задавать вопросы. Например, если пересечение ящиков не работает, тестовые ситуации вы знаете, какой будет правильный ответ. т.е. коробка с углом в (0,0,0) размера (1,1,1), пересекающаяся с лучом при (-1,0,5,0,5), движущимся вдоль (1,0,0), будет достигать отметки (0,0,5 , 0.5), такого рода вещи. Затем, когда вы приходите сюда, вы можете получить совет, а не просто использовать его в качестве службы проверки доказательств. –

ответ

3

Вы можете сделать код намного короче и читабельнее. Например, изменить int tNear = -2147000000 к int tNear = INT_MIN и изменить

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; 
} 

к

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

Тогда один участок кода становится:

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; 
} 

И это показывает одну проблему. tNear и tFar определяют интервал t значений, в пределах которых линия пересекает куб. Каждая согласованная вами проверка (x, y и z) дополнительно ограничивает интервал. Однако код tFar = max(tFar, t1) расширяет интервал. Измените его на tFar = min(tFar, t1).

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

Вы можете определить любой выпуклый многоугольник как множество бесконечных плоскостей с нормалями, обращенными наружу. Точка находится внутри многоугольника, если она «внутри» всех плоскостей.

Самолет разбивает пространство на две половины. Определите половину, к которой нормальные точки, как «снаружи», а другая половина - «внутри». Тогда точка находится вне плоскости, если плоское уравнение в этой точке положительно, внутри плоскости, если значение отрицательное и на плоскости, если значение равно нулю.

Чтобы проследить это, вы определяете пересечения лучей/плоскости и выбираете ближайший. Чтобы определить, находится ли эта точка внутри лица (помните, что плоскость бесконечна), вы проверяете, находится ли точка внутри всех других плоскостей. Если нет, проверьте ближайшее ближайшее пересечение и так далее.

Как только это работает, довольно легко распространить его на общие пересечения и разности форм (например, куб с полусферическим отступом на одной из граней).

5

Одним из лучших алгоритмов расчета пересечений лучей является slab method.Я также изложил свою оптимизированную реализацию here.

+0

Я уже получил свой метод с этого сайта, но в любом случае спасибо. – Chris

+0

Привет, Тавиан, я нашел это очень полезным! - но, этот метод должен уважать/понимать знак вектора направления? Поскольку линейное копирование вашей функции в Golang не кажется - я просто поднял вопрос SO здесь: http://stackoverflow.com/questions/9971105/slab-method-for-ray-box- пересечение-дает-ложные позитивы-для-противоположного directio – metaleap