Задача отбраковки прямоугольников Frustum

Я пытаюсь реализовать отсечение усеченного конуса в моей игре OpenGL 2d. Единственным видом геометрических объектов в моей игре на данный момент являются прямоугольники, поэтому я подумал, что это будет довольно просто, но получаю неожиданные результаты. Я установил симметричную перспективную проекцию с углом поля зрения 45 градусов, а также в ближней и дальней плоскостях 0,01 и 50 соответственно. Вектор глаза всегда параллелен оси z, камера может перемещаться только по осям x и y.

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

GLfloat maxDistance = givenRectangle.z * tanf(0.5 * (fovAngle * M_PI/180) );

Затем я складываю и вычитаю это расстояние до и от координат x и y камеры, чтобы получить максимальные и минимальные видимые x и y, а затем проверяю данный прямоугольник, чтобы увидеть, находится ли он между этими значениями.

Мой вопрос в том, на правильном ли я здесь пути и почему приведенная выше формула возвращает абсурдно маленькое значение (что-то * 10 ^ -37), когда у меня есть объект с z = 5, который должен быть четко виден камерой в ( 0,0,0)?


person Jacob    schedule 31.01.2011    source источник
comment
Да, технически у меня есть только двухмерные прямоугольники в трехмерной перспективе, так что, как бы вы это ни называли :) Я хочу перспективную проекцию, потому что я хочу иметь возможность увеличивать и уменьшать масштаб, у меня есть мир с ориентация камеры сверху вниз   -  person Jacob    schedule 31.01.2011
comment
не могли бы вы объяснить мне эту часть, пожалуйста: Затем я добавляю и вычитаю это расстояние от координат x и y камеры и от них, чтобы получить максимальные и минимальные видимые x и y, а затем проверяю данный прямоугольник, чтобы увидеть, находится ли он между ними ценности.   -  person jocelyn    schedule 23.01.2013


Ответы (1)


Взяв задачу сверху, я проверил вашу формулу - см. Рисунок, чтобы убедиться, что я правильно вас понял.

введите описание изображения здесь

Учитывая, что мы знаем A и Z и хотим найти X, я сначала написал:

загар (А) = X / Z

переставляя, получаю:

X = Z загар (A)

Поскольку Z = 5 и A = 22,5 градуса ...

X = 5 * загар (22,5 градуса)

X = 2.07106781

Итак, кажется, что вы правильно поняли математику, но ваш код ошибочен - возможно, ваша функция tan ожидает градусы, а не радианы, или fovAngle не был установлен? Я думаю, вам нужно отладить и проверить каждое значение вручную.


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

Имея точку на плоскости и нормаль к плоскости, вы можете довольно легко вычислить уравнение плоскости, которое, в свою очередь, упрощает проверку, находится ли данная точка« внутри »(в направлении нормали) данной плоскости. Пройдите по всем 6 плоскостям, и вы быстро сможете управлять заданной точкой в ​​вашем объеме просмотра или вне его.

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

person Community    schedule 04.03.2011
comment
Спасибо за ответ, я действительно это имел в виду. Я также выяснил, в чем проблема: это было что-то с двойным указателем на fovAngle, которое не работало должным образом в моем конкретном коде ... Один вопрос о вашем способе отсечения пирамиды: прав ли я, подозреваю, что этот более общий подход для простых прямоугольников медленнее, чем описанный мной метод? - person Jacob; 06.03.2011
comment
Рад, что вы нашли ошибку, звучит разочаровывающе. Да, метод самолетов наверняка будет медленнее. На каком-то этапе это могло бы сэкономить вам усилия при разработке, но в вашей конкретной ситуации это может оказаться излишним. - person Edward Dixon; 07.03.2011
comment
Говоря о скорости, если вы все равно пишете 2D-игру и действительно хотите сделать все возможное для повышения производительности, подумайте о том, чтобы не использовать перспективу. Если вместо этого вы используете ортогональную проекцию, ваш тест на наличие прямоугольника внутри экрана снова будет проще: 0 ‹x‹ screen_width. - person Edward Dixon; 07.03.2011
comment
Если вы хотите иметь возможность уменьшить масштаб сцены и посмотреть, виден ли объект или нет, вам нужна эта техника, даже в 2d! - person jocelyn; 22.01.2013