![]() |
Модераторы: Poseidon |
![]() ![]() ![]() |
|
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
С первым пунктом (вычисление периметра) все очевидно: идем по списку (состоящему из записей с тремя полями: x, y, next), накапливаем значение периметра (используя формулу расстояния между двумя точками с известными координатами: d^2=(x1-x2)^2+(y1-y2)^2); упростить процесс у меня не получилось (там же сумма корней получается, ничего с ней не сделаешь…). По части второго пункта (вычисление площади) есть тупая мысль просто взять лежащую внутри многоугольника точку, соединить ее со всеми вершинами, накапливать значение площади (складывая площади получившихся треугольников). Мне эта тупая мысль не нравится, но придумать что-то более элегантное пока не удалось. Третий пункт, проверка на выпуклось. Можно, конечно, исходить из геометрического определения выпуклости и проверять, лежит ли многоугольник по одну сторону от каждой из линий, соединяющих соседние вершины. Но интуиция мне подсказывает, что это слишком долго, нерационально и имеет мало общего с программированием ![]() Четвертый и пятый пункт меня пугают ![]() ![]() Помогите, пожалуйста ![]() ![]() |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 17 Всего: 454 |
1) да.
2) не сработает, ибо ошибочно. Использовать разбиение на треугольники. 3) проверка внешних углов при каждой вершине. 4) ликвидация "впуклых" вершин по одной. 5) непонятно, о чем речь -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 24 Всего: 110 |
вычислять площадь можно по такой формуле (то ли это формула Грина, то ли из неё выводится):
s=sum[i=1..N]( (x[i+1]-x[i])*(y[i+1]+y[i])/2 ) (ну ещё модуль взять) -------------------- qqq |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Скажем, есть у нас три пары координат: вершины А1, А2, А3. А3 / А2 \ А1 Как посчитать угол - понятно (через скалярное произведение векторов). А вот как определить, будет посчитанный угол внешним или внутренним? Ведь возможны обе ситуации: ![]() Для этого надо уметь определять "впуклые" вершины ![]() ![]()
Т.е. если смотреть со стороны периметра и площади, то нам больше всего подходит циклический способ организации динамического массива (проще говоря, мы должны указатель последней записи направить на первую). Да ![]() (большое спасибо за хорошую, очень удобную формулу ![]() |
|||
|
||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 24 Всего: 110 |
да, просто забыл уточнить по смыслу там просто идёт суммирование по отрезкам, ну а т.к. последний отрезок соединяет последнюю и первую вершины, то и получается циклический доступ
рассматривая отдельно взятый угол, определить внешний он или внутренний не получится нужно выбрать направление обхода вершин (вполне естественно взять то, в котором задан многоугольник) и для каждого угла выяснить, вправо он поворачивает или влево если везду происходит поворот в одну и ту же сторону - многоугольник выпуклый, иначе - нет Добавлено через 1 минуту и 53 секунды ну а вообще, в будущем я бы советовал создавать по одной теме на каждый вопрос, тогда и заголовок можно точнее написать, что увеичит вероятность захода в тему человека, которому это интересно ну а кроме того, по этим вопросам можно поискать, что уже есть на форуме если мне не изменяет память, то определение площади и выпуклости уже где-то проскакивало -------------------- qqq |
|||
|
||||
KasMP |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Определить это через скалярное произведение не получается: его знак говорит о том, что угол острый/прямой/тупой, а направление никак не задействовано. Если считать угол между векторами, то тоже не получается: arccos(x) - мы можем повернуть на x в любу сторону. Если считать изменение координат (например, абсцисса увеличилась и ордината уменьшилась, абсцисса и ордината увеличились, т.п.), то придется сначала искать крайние точки (нижнюю, левую, верхнюю, правую), потому что при переходе через эти точки изменение координат меняют значение: находимся между крайней левой и крайней верхней точками, увеличение абсциссы и ординаты - поворот вправо; находимся между крайней правой и крайней левой точками, увеличение абсциссы и ординаты - поворот влево. Как это определить? ![]() Учту на будущее ![]()
Уже пробовала ![]() ![]() |
||||
|
|||||
maxim1000 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: 24 Всего: 110 |
для этого можно использовать векторное произведение точнее - определитель, т.к. векторное произведение определяется в 3d ax*by-ay*bx будет иметь разный знак в зависимости от того, в какую сторону направлен угол между a и b -------------------- qqq |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Точно! Да и я сама вспомнила про векторное произведение, хотела открыть тетрадку и проверить, а вместо этого пошла на кухню делать ужин и так и забыла ![]() Спасибо еще раз ![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Итак, мы уточнили ![]() Пересечение двух выпуклых многоугольников. Пересечение - часть, принадлежащая обоим многоугольникам, вершины которых задаются с помощью двух координат. Например, 1) ((-5,-1),(2,7),(2,-1))*((-1,-1),(-1,2),(2,2),(4,0),(2,-3)) = ((-1,-1),(-1,2),(2,2),(2,-1))- многоугольник; 2) ((0,0),(0,1),(1,1),(1,0))*(0,0) = (0,0)- точка; 3) ((0,0),(0,1),(1,1),(1,0))*(5,5) = пустое множество; 4) ((0,0),(0,1),(1,1),(1,0))*((0,0),(0,5),(5,5),(5,0)) = ((0,0),(0,1),(1,1),(1,0))- первый многоугольник. Проверка принадлежности точки многоугольнику (возможно, невыпуклому). Тут все понятно ![]() (в смысле, задание понятно... а как делать - нефига непонятно!!!) Это сообщение отредактировал(а) KasMP - 18.5.2008, 16:19 |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Люди, ну помогите, пожалуйста, с принадлежностью точки многоугольнику!
Если с определением выпуклости я как-то справлюсь (примерно понятно, что и как делать), то с принадлежностью вообще все очень туго!!! ![]() ![]() |
|||
|
||||
Fortop |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2200 Регистрация: 13.11.2007 Где: Донецк Репутация: 1 Всего: 42 |
Подожди, почему туго.
Принадлежность точки треугольнику ты можешь определить? Добавлено через 1 минуту и 52 секунды Да, вот тебе статья навскидку http://ru.wikipedia.org/wiki/%D0%90%D0%BB%...%B8%D0%BA%D0%B5 Добавлено через 2 минуты и 52 секунды Вот тебе вторая статья http://algolist.manual.ru/maths/geom/belong/poly2d.php -------------------- Мир это Я. Живее всех живых. |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Не знаю, сейчас подумаю... Добавлено через 47 секунд
О! Там, похоже, что-то стоящее ![]() ![]() Добавлено через 2 минуты и 43 секунды Кстати, с пересечением тоже дела не очень... ![]() Пожалуйста, не бросайте на растерзание судьбы ![]() ![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Гм, и неужели нельзя изобрести такой треугольник и такую непринадлежащую ему точку, что указанная сумма площадей будет равно площади треугольника? Имхо если постараться, то может получиться ![]() (а с многоугольником точно должно получиться изобрести!) Это сообщение отредактировал(а) KasMP - 18.5.2008, 16:56 |
|||
|
||||
Fortop |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2200 Регистрация: 13.11.2007 Где: Донецк Репутация: 1 Всего: 42 |
KasMP,
С пересечением тоже можно поискать ссылки ![]() Не думая, алгоритмически я бы сделал так. Взял бы каждую сторону многоугольников и проверил бы на пересечение с каждой стороной другого. Если есть, то найти точки пересечения и определив направление обхода, бежал бы последовательно по узлам. Например. Если первое пересечение находится на стороне А1А2 и Б2Б3, а следующее А5А6 Б4Б5,то необходимо пробежаться по все фигуре от точки пересечения А1А2-Б2Б3 через А2А3, А4А5 до точки пересечения А5А6-Б4Б5 и назад через Б3Б4 до точки пересечения А1А2-Б2Б3. Хотя надо еще проверять выпуклость и впуклость. Плюс здесь же будет проверка вырожденого случая. Если один многоугольник целиком внутри другого. А вообще ![]() ![]() Добавлено @ 17:00 нет. Смотри, так как ты соединяешся с каждой вершиной. То площадь многоугольника ты захватишь в любом случае. Но если точка лежит вне, то ты захватишь еще и лишнего ![]() Добавлено через 4 минуты и 4 секунды KasMP, если что-то не можешь понять - нарисуй на бумаге ![]() А треугольник или многоугольник - разницы большой в этом случае нет. Это сообщение отредактировал(а) Fortop - 18.5.2008, 17:01 -------------------- Мир это Я. Живее всех живых. |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Да, но ведь нормальный программист должен хотя бы раз додуматься до всего этого сам. (или хотя бы поразмышлять на эту тему, чтобы понять все нюансы и всю красоту оптимального варианта, понять свои ошибки и сделать вывод на будущее) И действительно ![]() ![]() (я уже нарисовала ![]() |
|||
|
||||
Fortop |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2200 Регистрация: 13.11.2007 Где: Донецк Репутация: 1 Всего: 42 |
Это классно ![]() ![]() -------------------- Мир это Я. Живее всех живых. |
|||
|
||||
KasMP |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Я вчера наконец-то отошла от раздумий над алгоритмами и приступила к написанию программы.
Решила создать модуль, в котором будут нужные ВА. В модуле были созданы типы для списка и некоторые переменные:
После процедур считывания первой вершины и всех остальных идут периметр и площадь (это мне удалось достаточно быстро и легко). Прошу каких-нибудь рекомендаций, замечаний.
Дальше идет определение принадлежности точки многоугольнику: точка последовательно соединяется со всеми соседними вершинами, накапливается сумма площадей полученных треугольников (площадь каждого отдельного треугольника считается по формуле Герона); если накопленная сумма площадей равна площади многоугольника, то точка принадлежит многоугольнику (иначе не принадлежит, это понятно). Очевидно, что при подсчете площадей двух соседних треугольников длина одной и той же стороны будет нужна 2 раза. Это учтено: длина каждой стороны считается один раз, а в цикле просто переводятся указатели. Мне удалось найти у себя несколько ошибок: периметр вместо полупериметра, непереведенные на вершину вперед указатели и т.п.. Но функция по прежнему всегда выдает false.
В упор не могу найти еще ошибки (помогите, пожалуйста). Ну и сама программа, в которой все это тестируется, выглядит так:
Это сообщение отредактировал(а) KasMP - 20.5.2008, 07:59 |
||||||||||
|
|||||||||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
![]() ![]() ![]() Я вместо массива организовала динамический список ![]() |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 5 Всего: 260 |
я так понял, у тебя сравниваются площади "строго равно". все же у тебя дробный тип данных.
воспользуйся сравнением "отлиается на некую погрешность". ну, так отладь функции в отдельности. корми тестовые данные, смотри дебаггером текущие значения переменных. сравнивай с ожидаемым. когда функции в отдельности будут отлажены и проверены по мере сил, приходи к тестированию программы в целом. а то даже с помощью целого форума искать ошибку в непростом коде - вещь небыстрая, малоинтересная и низкоинформативная ![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
skyboy,
![]() (очень рада тебя видеть!!!)
![]() ![]() ![]() Т.е., другими словами, взять модуль разности суммы площадей треугольников и площади многоугольника, а затем сравнить этот модуль с какой-то положительной величиной? Я так и делаю ![]() ![]() |
|||
|
||||
Fortop |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2200 Регистрация: 13.11.2007 Где: Донецк Репутация: 1 Всего: 42 |
Если в Delphi нет специальной функции, то алгоритм описан правильно ![]() главное чтобы эта положительная величина была достаточно мала ![]() -------------------- Мир это Я. Живее всех живых. |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Подумаем, сколько это должно быть... Только проблема в том, что функция проверки принадлежности точки многоугольнику выдает false даже тогда, когда результаты всех вычислений, всех извлечений корней целочисленны ![]() ![]() |
|||
|
||||
Fortop |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2200 Регистрация: 13.11.2007 Где: Донецк Репутация: 1 Всего: 42 |
KasMP,
А что тут искать? бери треугольник со сторонами 3, 4, 5 переведи на листике его в векторы и точку где-нибудь внутри. затем заданные значения просчитай своей функцией и выведи результат суммы площадей. -------------------- Мир это Я. Живее всех живых. |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
О
![]() Сегодня запустила тот же самый код на другом компе - функция работала идеально ![]() ![]() Как такое может быть ![]() ![]() (может память надо чаще очищать ![]() ![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Сделала все кроме пересечения двух многоугольников (вторым "многоугольником" может быть точка). Про пересечение буду читать вот это.
Сдавать в классе мы уж не успеваем, поэтому буду писать на e-mail. Я попробовала прокомментировать модуль и саму программу так, чтобы преподаватель понял, откуда что взялось. Не могли бы вы оценить то, насколько понятно получилось? Помогите, пожалуйста, своей оценкой. Я нисколько не хочу, чтобы преподаватель увяз в дебрях переменных, связей между ними и т.п.. Хочется, чтобы ему было не очень сложно и чтобы он не мучился слишком сильно... (видимо, придется посылать два варианта: с комментариями и без - уж слишком много их получилось) |
|||
|
||||
THandle |
|
|||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 30 Всего: 372 |
KasMP, покажи что у тебя получилось, почитаю
![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Сейчас
![]() Добавлено через 2 минуты и 44 секунды Эм... Если открыть *.pas в блокноте, выбрать шрифт "Terminal", скопировать и вставить сюда, то вместо кириллицы получается абракадабра. Если выбирать не "Terminal", то получается абракадабра и в блокноте, и здесь... ![]() Добавлено через 3 минуты и 58 секунд Как перенести кириллицу из *.pas (т.е. из-под MSDOS) сюда (т.е. в Windows)? |
|||
|
||||
THandle |
|
|||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 30 Всего: 372 |
KasMP, прикрепи сам файл
![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Так не все будут качать... Кто-то по ссылке до статьи дойти не может, а тут тем более...
Присоединённый файл ( Кол-во скачиваний: 4 ) ![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Там 5 файлов: модуль с комментариями и без, программа с комментариями и без, формула для площади многоугольника.
Добавлено через 7 минут и 44 секунды Я вспомнила, что забыла очистить память!!!!!! Добавлю потом... Считайте, что память очищена ![]() Добавлено через 10 минут и 54 секунды Да, кстати, вам потребуется файл входных данных. Можете взять этот:
Присоединённый файл ( Кол-во скачиваний: 3 ) ![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Если кому-то интересно, то с этими входными данными
|
|||
|
||||
THandle |
|
|||
![]() Хранитель Клуба ![]() Награды: 1 Профиль Группа: Админ Сообщений: 3639 Регистрация: 31.7.2007 Где: Moscow, Dubai Репутация: 30 Всего: 372 |
KasMP, ну в общем все чем мог помочь написал в ПМ, для форума это особой ценности не представляет
![]() |
|||
|
||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
||||
|
||||
KasMP |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Так, пересечение
![]()
Посидев над этой табличкой, я выбрала алгоритм О'Рурка для выпуклых многоугольников (а случай с многоугольником и точкой рассмотрю отдельно, на это много ума не надо...).
Честно говоря ![]() ![]() |
||||
|
|||||
KasMP |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 586 Регистрация: 8.8.2006 Репутация: 1 Всего: 30 |
Люди, ну помогите пожалуйста разобраться с алгоритмом О'Рурка!
(моя тема чем-то хуже остальных?) |
|||
|
||||
Fortop |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2200 Регистрация: 13.11.2007 Где: Донецк Репутация: 1 Всего: 42 |
KasMP, судя по всему он очень похож на то, что я тебе предлагал в самом начале.
Перебирать все ребра и проверять пересекаются ли они между собой. или посмотри эту ссылку http://progs-maker.narod.ru/algor.html -------------------- Мир это Я. Живее всех живых. |
|||
|
||||
volvo877 |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2073 Регистрация: 15.11.2004 Репутация: 34 Всего: 116 |
Наверное, лучше всего обратиться к первоисточнику - книге О'Рурка "Вычислительная геометрия на С". Вот тут лежат исходники из этой книги: http://maven.smith.edu/~orourke/books/ftp.html (тебе нужен Int Conv Poly)
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "Центр помощи" | |
|
ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Более подробно с правилами данного раздела Вы можете ознакомится в этой теме. Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Центр помощи | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |