Есть тут знатоки геометрии? Помощь требуется...

Башуров В.В.

Вообщем, я тут конвертирую свой План Качканара для Google Earch в формат freeware редактора карт MapEdit с целью довести ее "до ума": дорисовать дороги, исправить дома и т.д. Поскольку план рисовался вручную, практически все дома не имеют идеально прямых углов. Хотелось бы исправить эту ситуацию автоматически. Попробовал придумать алгоритм сам, но, увы, геометрия никогда мне хорошо не давалась. Прошу помощи зала!!! :)

Задача:

Имеется многоугольник заданный массивом координат узлов. Требуется проверить угол на каждом из узлов и, если он лежит в пределах 87-93 градусов, довести его до 90 равномерно увеличив/уменьшив длину сторон. При этом учесть, что углы могут быть как внешними, так и внутренними.

Решение можно сделать как в виде готовой функции на наиболее близком вам языке программирования (я без труда читаю Basic, C, Pascal, Foxpro и, разумеется, PHP), либо просто описанием алгоритма.

Комментарии
Башуров В.В.

Дополню: многоугольник расположен на плоскости, а не в 3D. В описании алгоритма хотелось бы увидеть готовые формулы. Ибо как раз в формулах я не силен...

Петеримов С. (sp)

Чет не совсем вник в задачу :( А не проще без углов, просто сравнивать длинну сторон (по видимости противоположных), если она не равна, то угол не равен 90%. Попарно уравниваем стороны получаем дома в виде ромбов :))

Magic™

Вова вот у меня идея возникла ... незнаю правильно или нет. Сначала расскажу, потом могет по пробую написать.

Вообшем смотри мы получаемся знаем длинны сторон. через узел проводим линию которая имеет две длины второй стороны. Если конец или начало новой линии не равно координате следуюшего узла (конец второй стороны) то начинаем прибавлять длину первой.

Петеримов С. (sp)#2: Серега ты не так понял Вова же сказал что угол как внутринний так и в нешний.

Башуров В.В.

Magic™#3: Мммм... Не уверен, что правильно понял алгоритм, но одно могу сказать точно: у квадрата и ромба будут все стороны равны, а вот углы - увы... Т.е. без вычисления именно углов не обойтись.

zbp

Башуров В.В.#4: Так изумительно наблюдать за компьюристами, везде ищущих алгоритмы... Возможно я их решу при более конкретизированной задаче по 3-D. А пока могу только просчитать недостающие элементы - по геометрии у меня в 1983 году было твердая "5"... Ну, с учетом навыка - еще накопал... Короче - в чем "борода"?

Башуров В.В.

Захаров Б.П.#5: Возможно Вас это удивит, но большинству программистов совсем не обязательно знать обычную математику более, чем в базовых четырех действиях. Вот бинарную математику-логику знать надо, просто потому, что сам компьютер именно бинарной математикой пользуется. А какие-то более сложные вещи постановщик решает, который, в свою очередь, не обязан знать конкретные языки программирования. А для всяких настроечно-админских дел и вовсе математика почти не нужна - там важно понимать процессы, происходящие в той или иной ситуации.

Что касается задачи - задача вполне четко сформулирована в топике и первом комментарии. Повторюсь, что 3D не требуется - все вычисления на плоскости.

Петеримов С. (sp)

Володь, с прямоугольниками все достаточно просто - уравниваем стороны, получаем ромбы, квадраты, прямоугольники, параллелограммы. Затем берем три узла полученого четырехугольника (получается техугольник), и тянем основание (один из катетов, две точки) пока квадрат гипотенузы не будет равен квадрату катетов. В итоге получим правильные фигуры - кватраты и четырехугольники. :)

Башуров В.В.

Петеримов С. (sp)#7: Вот это вот "тянем" - это что в цикле по-чуть-чуть? :) Я чувствую, что тут должны быть однозначные решения, буз подбора...

Петеримов С. (sp)

Башуров В.В.#8: Углы-то у тебя разные в мноугольниках. Хотя, если можно установить сначало прямой угол (любой в четырехугольнике), а потом выровнять стороны, то в итоге тоже получатся правильные фигуры. :)

Nata

В случае, когда передвигается боковой узел, а длина стороны остается неизменной, есть решение: Найти угол, вычислить разницу- на сколько отличается от 90, затем вычислить необходимый сдвиг - величину этого сдвига, а затем расположение. На бумаге и с чертежами получается, в виде алгоритма сложнее, поэтому позже. Формулы которые используются: вычисление длины стороны по координатам, связь сторон и углов, та что с косинусами, и обратное нахождение координат по системе из двух уравнений с двумя неизвестными.

maxx

Если касается геометрии, то создаём стандартную ось координат, выбираем 3 узловые точки и помещаем начало координат в угловую точку, направление оси (скажем Y) через любую из 2 оставшихся точек, получаем выравнивание по одной координате, далее нужно определиться с расположением последней точки и , собственно какой это угол внешний или внутренний, это можно сделать обычным опросом: Y в "+" или в "-" Х в "+" или в "-" 1 четверть (Y в "+" и Х в "+") угол 90, 2 четверть (Y в "+" и Х в "-")угол 180, 3 четверть (Y в "-" и Х в "-") угол 180, 4 четверть (Y в "-" и Х в "+") угол 360, (под углом будем понимать уголобразованный осью Х и неопределённой точкой) в итоге получаем выравнивание по 2м координатам, т.е 90 град. Можно конечно обойтись только углами "0" и "180" но неивестно как машина это воспримет.

Nata

Если рассматривать замкнутый многоугольник, перебирая его углы, то может оказаться ситуация, когда дойдя до последнего угла, его подправили и тем самым сбили первый угол. Если это прямоугольник, то все просто - не надо последний угол трогать, он сам выровняется, а вот если что другое?

Второй вопрос, а нельзя ли угол двигать по вертикали или горизонтали вместо увеличения-уменьшения сторон. просто в этом случае формулы попроще, а параллельность отдельных линий для разных многоугольников все равно слетает?

Решение задачи в любом случае (перенос узла, выравнивание одной из линий, увеличение-уменьшение сторон) существует, только вот формулы многоэтажные получаются - все длины и углы через координаты точек вычисляются. Небольшая проблема при вычислении - направление сдвига в + или - зависит от расположения узлов в пространстве, формулами не вычисляется, придется проверять подстановкой

А вот внешний это или внутренний угол, нет никакой разницы -все равно рассматривается треугольник из проверяемого узла и двух соседних.

Башуров В.В.

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

Что бы было проще: многоугольники все имеют четное количество углов. Поэтому ситуации "последний угол не прямой" не получается. Если хотя бы один из углов имеет отклонение от 90' более чем на 20' - эту фигуру не рассматриваем. В остальном: подавляющее большинство зданий в Качканаре имеет прямые углы. Исключения: 12-этажки, "клюшка" и здания внизу 10-го мк. С исключениями я работать буду индивидуально. :)

У меня тут в голове алгоритм нарисовался занятный, но в формулы пока не могу перевести:

  1. Проходим по всем нечетным сторонам и находим их углы относительно системы координат.
  2. То-же для четных сторон, но с вычитанием 90'.
  3. Получаем среднее арифметическое от всех углов из пунктов 1-2 - считаем это углом поворота всей фигуры. Назовем его "d".
  4. Теперь все нечетные стороны делаем параллельными прямой с углом d. Отрезки сторон лучше вращать относительно их середины, но можно и относительно одной координаты для простоты.
  5. Все четные стороны аналогично делаем перпендикулярными прямой d.

В итоге получаем везде прямые углы и полное отсутствие "подбора" значений в решении задачи. Даже, вроде, условий никаких не получается - все тупо на одних формулах...

maxx

Если чем то поможет, то у меня есть карта Качканара в pdf неплохо выполненная как раз в геометриии... :)

Башуров В.В.

maxx#14: В pdf я ее самолично конвертил... ;-)