Задан прямоугольник и точка с векторным направлением к прямоугольнику. Как я могу найти ближайшую точку снаружи этого прямоугольника к рассматриваемой точке?
Задан прямоугольник и точка с векторным направлением к прямоугольнику. Как я могу найти ближайшую точку снаружи этого прямоугольника к рассматриваемой точке?
Ответы:
Одна из техник, которую вы могли бы использовать, называется «лучевое литье». Он обычно используется для визуализации графики, но имеет другие приложения, такие как прямая видимость (как вы хотите сделать) и поиск пути. В общих чертах это работает, находя пересечение луча и объекта. В вашем примере луч - это вектор направления персонажа.
Полезная ссылка для пересечений лучей / объектов (и, между прочим, других пересечений объектов / объектов) - www.realtimerendering.com/intersections.html (см. Ссылки для ray / aabb и ray / obb).
Прямоугольник имеет четыре стороны. Каждая сторона представляет собой отрезок.
Проверьте каждую из четырех сторон на пересечение с лучом. Отслеживать ближайший хит.
Вот некоторый код, чтобы узнать, где в сегменте попадает луч:
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
}
Если ваш прямоугольник выровнен по оси, вам просто нужно прикрепить каждую координатную ось к прямоугольнику, если точка находится за пределами прямоугольника.
Из 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
будет отброшено к ближайшей стене коробки, если она находится вне коробки с самого начала. если он уже находится внутри коробки, он останется один (там, где он есть).
Ну, вы можете использовать только линейную алгебру (если быть более точным, аналитическую геометрию), чтобы решить эту проблему. Это зависит от того, как вы смоделировали прямоугольник.
Вот общий случай: http://paulbourke.net/geometry/lineline2d/