|
Лекции по структурам и алгоритмам обработки данных (СиАОД) 14В выпуклом четырехугольнике каждые две противоположные вершины лежат по разные стороны относительно диагонали, соединяющей две другие вершины. Если же четырехугольник не является выпуклым, то относительно одной из диагоналей две вершины находятся по одну сторону. Если вывести уравнение диагонали по двум точкам в виде AX + BY +C = 0 (в частных случаях A = 0 или B = 0), то выражение Z = AX + BY +C обращается в 0 на диагонали и имеет разные знаки в точках по разные стороны диагонали. Остается для каждого четырехугольника вывести уравнения диагоналей и проверить для обеих диагоналей указанные условия, подставляя координаты вершин в выражение для Z. Приведем текст программы для решения этой несложной задачи. Program FourAng;
Выпуклая оболочка. На плоскости заданы своими декартовыми координатами N точек. Найти минимальный периметр многоугольника, содержащего все эти точки. Определить площадь этого многоугольника. Гарантируется, что искомый многоугольник имеет ненулевую площадь. Ввод из файла INPUT.TXT. В первой строке находится число N, далее - N строк с парами координат. Вывод в файл OUTPUT.TXT. Вывести с одним знаком после запятой: в первой строке - длину периметра, во второй - площадь. Ограничения: 3 ≤ N ≤ 1000, -1000 ≤ xi, yi ≤ 1000, все числа целые, все точки различны, время 2 с. Пример
5.7 2.0 Во-первых, искомый многоугольник должен быть выпуклым. Во-вторых, вершины многоугольника должны совпадать с какими-то из заданных точек. Оба эти свойства доказываются от противного. Данный многоугольник называется выпуклой оболочкой множества точек.Опишем алгоритм Джарвиса как наиболее известный способ построения выпуклой оболочки [2-4, 6]. Сначала находится первая вершина многоугольника. Например, из множества самых нижних вершин выбирается самая левая. Найдем другие вершины в порядке обхода точек по часовой стрелке, предполагая сначала, что все точки различны. Возьмем вектор (-1, 0) и обозначим его как (d1, d2). Вторая вершина выбирается так, чтобы угол между вектором (d1, d2) и вектором из первой вершины во вторую был минимален. Можно сказать, что вторая точка получается минимальным поворотом вектора (d1, d2) из первой точки по часовой стрелке. Если таких точек несколько, то возьмем наиболее удаленную из них. Далее вектором (d1, d2) будем считать вектор из первой точки во вторую и будем находить следующую точку и т. д. Все продолжается, пока снова не придем в первую точку. Минимальный угол можно найти с помощью скалярного произведения векторов. Ему соответствует максимальное значение косинуса, изменяющегося от -1 до 1. Поскольку некоторые точки могут повторяться, при поиске следующей вершины многоугольника не нужно исследовать точки, совпадающие с текущей вершиной. Трудоемкость этого алгоритма O(N2), где N – количество точек. Иногда его называют алгоритмом обертки. Действительно, можно представить, что точки на плоскости соответствуют вбитым гвоздикам, вокруг которых натягивают ленту. Есть более быстрый алгоритм Грэхема [3, 4, 6], трудоемкость которого O(N logN). Снова из множества самых нижних вершин выбирается самая левая. Обозначим ее A0. Точка A0 заведомо принадлежит выпуклой оболочке. В нее переносится центр координат. Остальные вершины сортируются одним из методов быстрой сортировки по возрастанию полярного угла. Если несколько точек имеют одинаковый угол, то оставляется одна с максимальным радиус-вектором. Обозначим оставшиеся точки A1, A2, …, AM в соответствии с порядком сортировки. Будем последовательно, т.е. в направлении против часовой стрелки рассматривать тройки точек Ak-1, Ak, Ak+1. С помощью векторного произведения найдем ориентированную площадь треугольника Ak-1AkAk+1. По знаку площади можно определить, находится ли точка Ak внутри треугольника A0Ak-1Ak+1. Если это так, то точка Ak исключается. Сейчас уже точка Ak-1 может находиться внутри треугольника A0Ak-2Ak+1. Как только исключение промежуточных точек завершается, можно перейти к следующему значению k. По окончанию обхода оставшиеся точки будут углами многоугольника, являющегося выпуклой оболочкой. Найдем площадь многоугольника. Пусть даны две точки A(X1,Y1) и B(X2,Y2). Площадь S трапеции, образованной отрезком AB, определяется как SAB = (X1 - X2) * (Y1 + Y2) / 2 На самом деле полученное значение может оказаться отрицательным, поэтому его нужно взять по модулю, но нам потребуется именно площадь со знаком. Площадь всего многоугольника получается суммированием по всем сторонам при последовательном обходе в определенном направлении, то есть S = S(1, 2) + S(2, 3) +…+ S(N, 1), где S(i, j) – площадь со знаком трапеции, соответствующей очередной стороне многоугольника. Действительно, если считать для наглядности, что многоугольник расположен выше оси X и обход производится по часовой стрелке, то "лишняя” площадь под нижними сторонами многоугольника вычитается при их обходе. Если порядок обхода вершин неизвестен, нужно снова взять полученное значение по модулю. Приведем текст программы.
Задачи для самостоятельного решения
В декартовой системе координат на плоскости заданы координаты вершин треугольника и еще одной точки. Определить, принадлежит ли эта точка треугольнику. Ввод из файла INPUT.TXT. В четырех строках находятся пары чисел - координаты точек. Числа в первых трех строках - это координаты вершин треугольника, в четвертой строке - координаты тестируемой точки. Вывод в файл OUTPUT.TXT. Вывести In, если точка находится внутри треугольника, или Out - если снаружи. Ограничения: координаты вершин - целые числа, для любой точки выполняются следующие условия: -10000 <= x, y <= 10000, время 1 с. Примеры
Маршрут движения автомобиля задан в виде координат вершин ломаной. Необходимо определить количество левых поворотов (смежные участки ломаной не лежат на одной прямой). Автомобиль начинает движение из первой вершины ломаной. Ввод. Первая строка состоит из одного числа N (3 N 1000), количества звеньев ломаной. В последующих строках - пары натуральных чисел (Xi, Yi), координаты вершин ломаной (-104 Xi, Yi 104). Вывод. Выходной файл содержит одно число - количество левых поворотов. Пример Ввод
|
Loading
|