ПРОГРАМИРУЕМ 3D ГРАФИКУ ИСПОЛЬЗУЯ DirectX



Проверка попадания - часть 11


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

С проверкой принадлежности точки многоугольнику мне пришлось изрядно повозиться. Один из способов выяснить, лежит ли точка внутри многоугольника, — провести линию из данной точки в другую, находящуюся внутри многоугольника, и подсчитать, сколько раз эта линия будет пересекать его стороны. Нечетное количество пересечений означает, что точка находится за пределами многоугольника, как показано на Рисунок 7-4.

Рисунок, 7-4. Проверка принадлежности точки многоугольнику


/b> ily Глава 7. Проверка попадания

Сначала я поступил, немного глупо и решил написать код проверки самостоятельно. Я провел несколько часов, стараясь учесть все возможные случаи, и довольно близко подошел к ответу, когда здравый смысл все же взял верх. Я подумал, что на эту задача наверняка уже есть ответ и что найти его, вероятно, нетрудно. И оказался прав! Я отыскал нужный код в серии книг «Graphic Gems» (Academic Press) и приготовился вставить его в свою программу, когда меня посетила еще одна мысль. Вдруг такая функция уже имеется в Windows? После быстрого просмотра Microsoft Developer Library я нашел то, что искал, и окончательный вариант функции проверки (которая находится в файле SdMath.cpp) выглядит следующим образом:

BOOL _3dPointInPolygon(POINT* Points, int nPoints,

CPoint pt) {

HRGN hrgn = ::CreatePolygonRgn(Points, nPoints, WINDING);

ASSERT(hrgn) ;

BOOL b = ::PtInRegion(hrgn, pt.x, pt.y);

::DeleteObject(hrgn) ;

return b;

}

Я воспользовался интерфейсом GDI для создания многоугольной области, а затем завершил проверку функцией PtInRegion. Из всего этого я сделал один важный вывод: то, что я не пользуюсь функциями GDI в основной части своего проекта, еще не значит, что я вообще не должен пользоваться ими.

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




Содержание  Назад  Вперед