|
|||||
Сортировка. Защита и сокрытие информации. Атаки и взлом. Сжатие информации и кодирование. СRC. Графика и обработка изображений. Фракталы. Поиск в строках, массивах, последовательностях. Разбор выражений. Компиляторы и интерпретаторы. Cтруктуры данных. Хранение информации. AI, ГА, Нейронные сети. Вейвлеты. Игры, и все с ними связанное. Разное. Софт: просмотр PS и PDF файлов. Написать веб-мастеру Почитать историю сайта. |
Математика: Вычислительная геометрия.Проверка принадлежности точки многоугольнику.Случай треугольника.Для треугольника существует стандартный алгоритм, который надо знать, хотя и более общий тоже годится. Это - 'классика' аналитической геометрии, и в ручных расчетах используется именно он. char BelongToPoly (point a, point b, point c, point p) // Определение принадлежности точки треугольнику { float tmp1, tmp2; char f1, f2, f3; // Флажки /* Для определения принадлежности точки треугольнику используется следующий алгоритм: вся плоскость делится прямой, содержащей сторону треугольника, на две полуплоскости. Далее смотрим, если наша точка и противоположная этой стороне вершина треугольника лежат в разных полуплоскостях, то точка не принадлежит треугольнику. Такую проверку надо провести для всех 3-х сторон !!!!! */ // Проверяем сторону AB // Hаходим её уравнение y(x) по двум точкам // Если точка P и точка C лежат в разных полуплоскостях, // то произведение // (y(p.x)-p.y)*(y(c.x)-c.y) будет отрицательным // Уравнение прямой имеет вид: // y(x)=((x-a.x)*(b.y-a.y))/(b.x-a.x)+a.y tmp1=((p.x-a.x)*(b.y-a.y))/(b.x-a.x)+a.y-p.y; tmp2=((c.x-a.x)*(b.y-a.y))/(b.x-a.x)+a.y-c.y; if (tmp1*tmp2>=0) f1=1; // То же проделываем для стороны BC tmp1=((p.x-b.x)*(c.y-b.y))/(c.x-b.x)+b.y-p.y; tmp2=((a.x-b.x)*(c.y-b.y))/(c.x-b.x)+b.y-a.y; if (tmp1*tmp2>=0) f2=1; // Аналогично для стороны CA tmp1=((p.x-c.x)*(a.y-c.y))/(a.x-c.x)+c.y-p.y; tmp2=((b.x-c.x)*(a.y-c.y))/(a.x-c.x)+c.y-b.y; if (tmp1*tmp2>=0) f3=1; // Точка принадлежит if ((f1 == 1)&&(f2 == 1)&&(f3 == 1)) return (1); // Точка не принадлежит else return (0); } Выпуклый многоугольник.Теперь дадим общий алгоритм, пока только для выпуклых многоугольников. Alexandr Ivanov Пусть (x1,y1), (x2,y2), ... ,(xn,yn) - координаты точек полигона на плоскости. Сразу поясню, что координаты точек заданы в порядке обхода полигона в какую либо (любую) сторону, и стороны полигона не пересекаются (в последнем случае алгоритм тоже может работать корректно, но при дополнительных условиях) Xo,Yo - координаты точки,далее в цикле находим знак для каждого из векторных произведений Vn=(Xn+1-Xn)*(Yo-Yn)-(Xo-Xn)*(Yn+1-Yn)Zn=Sign(Vn) где Vn - значение в.п. для n-ной пары векторов, а Sign - функция возвращающая знак величины. Надо отметить, что в этом цикле при n = количеству вершин, n+1 = 1 (я думаю почему - и так понятно). Что мы делаем в геометрическом смысле ?
Таким образом, если точка внутри, то знаки всегда будут одинаковы - проверьте сами, Если же заранее известен обход вершин (например по часовой стрелке), то можно последнее условие упростить: если среди знаков есть '-' (для данного примера), то точка лежит вне, иначе внутри. Произвольный многоугольник.С произвольным многоугольником можно поступить гораздо проще, причем алгоритм будет включать и все предыдущие случаи. Проводим горизонтальную прямую через точку и сортируем координаты пересечений со сторонами по x. Если точка на четном месте - она внутри, на нечетном - снаружи. Отдельно рассматриваем случай нуля и лежит ли точка на пересечении линии со сторонами - иначе могут быть глюки. Алгоритм гораздо компактнее, но кода придется писать гораздо больше. Не забудьте разобрать случаи, когда точка лежит на сторонах. Вверх по странице, к оглавлению и навигации.
|