Найти ближайшую точку вдоль прямоугольника, учитывая другую точку и направление

8

Задан прямоугольник и точка с векторным направлением к прямоугольнику. Как я могу найти ближайшую точку снаружи этого прямоугольника к рассматриваемой точке?

Точка, обращенная к прямоугольнику

onedayitwillmake
источник
Можете ли вы объяснить больше, что вы спрашиваете? Я действительно не понимаю этого.
Допустим, у меня есть персонаж, обращенный к объекту (прямоугольник), и я рисую воображаемую линию от этого символа к прямоугольнику. Я хотел бы знать, как я могу определить, какая точка на внешней стороне прямоугольного объекта касается линии.
onedayitwillmake
1
Ключевое слово для поиска в Google - «AABB» (ограничивающий прямоугольник). Если ваш «прямоугольник» еще не выровнен по оси, сначала можно использовать простую матрицу преобразования - очевидно, используемую для всех элементов, которые вас интересуют, - чтобы изменить ее на единицу.
Мартин Сойка

Ответы:

6

Одна из техник, которую вы могли бы использовать, называется «лучевое литье». Он обычно используется для визуализации графики, но имеет другие приложения, такие как прямая видимость (как вы хотите сделать) и поиск пути. В общих чертах это работает, находя пересечение луча и объекта. В вашем примере луч - это вектор направления персонажа.

Полезная ссылка для пересечений лучей / объектов (и, между прочим, других пересечений объектов / объектов) - www.realtimerendering.com/intersections.html (см. Ссылки для ray / aabb и ray / obb).

Люк Ван Ин
источник
9

Прямоугольник имеет четыре стороны. Каждая сторона представляет собой отрезок.

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

Вот некоторый код, чтобы узнать, где в сегменте попадает луч:

bool intersect(const ray& ray, const segment& segment,point& hit) {
    // where do we intersect this line?
    float t = ((ray.direction.x * ray.origin.y + ray.direction.y *
        (segment[0].x - ray.origin.x)) -
        (ray.direction.x * segment[1].y)) /
        (ray.direction.y * (segment[0].x + segment[1].x) -
        ray.direction.x * (segment[0].y + segment[1].y));
    if(t >= 0.0 && t<=1.0) { // in the segment
        hit = segment[0] + (segment[1]-segment[0]*t);  // lerp
        return true;
    }
    return false; // no hit
}
Будет
источник
1

Если ваш прямоугольник выровнен по оси, вам просто нужно прикрепить каждую координатную ось к прямоугольнику, если точка находится за пределами прямоугольника.

Из RTCD стр. 130:

// Do this for all 3 axes
if( point.x < min.x )  point.x = min.x ;
else if( point.x > max.x )  point.x = max.x ;

Если вы сделаете это для осей x, y, z, то оно pointбудет отброшено к ближайшей стене коробки, если она находится вне коробки с самого начала. если он уже находится внутри коробки, он останется один (там, где он есть).

bobobobo
источник
0

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

Вот общий случай: http://paulbourke.net/geometry/lineline2d/


источник