трехмерное пространство, найти радиус |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
трехмерное пространство, найти радиус |
klem4 |
Сообщение
#21
|
Perl. Just code it! Группа: Пользователи Сообщений: 4 100 Пол: Мужской Реальное имя: Андрей Репутация: 44 |
lapp, а пост # 15 ты учел ?
-------------------- perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
|
bairt |
Сообщение
#22
|
Группа: Пользователи Сообщений: 5 Пол: Мужской Репутация: 0 |
lapp, а пост # 15 ты учел ? тогда можете проверить етот код uses crt; Теги ! |
Lapp |
Сообщение
#23
|
Уникум Группа: Пользователи Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
lapp, а пост # 15 ты учел ? Да, klem4, учел. Вообще-то хотя бы минимум комментариев, просто как жест вежливости и уважения к читающим, не помешал бы.. Да, я просмотрел программу, потом функцию из поста №15, сравнил, разобрался, что именно ты исправлял, и именно поэтому написал, что тебе следовало бы обратить чуть больше внимания на пост Бравого генерала. Ну и, кроме того - ты просил тестовые данные? Я тебе их дал. Ты проверил? Рекомендую проверить не только на программе, но и на листочке, с рисунком. Тогда ты поймешь, о чем говорил Бравый, и о чем я сейчас толкую. Ок? bairt, тебя нельзя упрекнуть в отсутствии комментариев - в твоей проге есть один! Но этого все же недостаточно.. Я очень извиняюсь, но рыскать глазами, ослеживая переменные, даже не представляя сначала, что же хотел сказать автор - ну, согласитесь, это носненс. Ну ладно еще, если бы алгоритм был известен. Тут же задача именно на составление алгоритма, а не программы! А еще лучше - дать параллельно краткое описание алгоритма. Ну, кто со мной не согласится? Ладно унимаюсь.. Короче, одного взгляда близорукого человека издалека на обе проги достаточно, чтобы сказать, что они не могут быть верными. Алгоритм, насколько я сейчас понимаю, гораздо сложнее, и к тому же он включает громоздкие математические вычисления. Сейчас я налью себе чаю и попробую описать, чего мне удалось надумать.. Если, конечно, кто нибудь не выложит верное решение раньше (или klem4 или bairt не докажут, что они правы). -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Бравый генерал |
Сообщение
#24
|
Новичок Группа: Пользователи Сообщений: 39 Пол: Мужской Реальное имя: Василий Репутация: -2 |
Цитата lapp, а пост # 15 ты учел ? klem4, ты так сказал, как будто после того поста решение КАРДИНАЛЬНО изменилось. Да, охватывающая сфера должна охватывать сферы, а не их центры, но сам костяк этого алгоритма неверен. Цитата Алгоритм, насколько я сейчас понимаю, гораздо сложнее, и к тому же он включает громоздкие математические вычисления. Во-во! Цитата и для наглядности сначала делал с окружностями, типа в 2D Вобщем, чтобы с тем неправильным алгоритмом было все ясно, вот эта программа - тот же алгоритм только в 2D, чтобы можно было проверить визуально. Бывают конечно случаи, когда охватывающая окружность охватывает ВСЕ окружности, но часто бывает, что сферы "вылазят" за охватывающую сферу, что и доказывает неправильность алгоритма. Uses Добавлено позже: Цитата Бравый генерал, я сначала пропустил это, а сейчас перечитал и увидел: твое утверждение неверно. Вот опровергающий пример. Да, прошу прощения, это я не то что-то сказал... (Ой, надо было в предыдущий пост добавить, а я случайно новым отправил.) |
klem4 |
Сообщение
#25
|
Perl. Just code it! Группа: Пользователи Сообщений: 4 100 Пол: Мужской Реальное имя: Андрей Репутация: 44 |
Да, теперь я понял, что был не прав, извиняюсь.
И всеже мне кажется что решение должно быть простым, еще одна идея есть, завтра сделаю. Сообщение отредактировано: klem4 - -------------------- perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
|
Lapp |
Сообщение
#26
|
Уникум Группа: Пользователи Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Да, теперь я понял, что был не прав, извиняюсь. И всеже мне кажется что решение должно быть простым, еще одна идея есть, завтра сделаю. Извиняться тут абсолютно не за что O'kay, делай. Я пока подожду постить свое решение. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Lapp |
Сообщение
#27
|
Уникум Группа: Пользователи Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Выполняю обещанное - публикую анонсированное мной в одном из предыдущих постов решение задачи. То есть не решение, а только алгоритм в самом общем виде. Более того, в нем присутствуют нерешенные математические выражения. Программый код к этой задаче я стал бы писать только под дулом банкомата, и желательно как можно более крупного калибра .
Сначала извинюсь перед Бравым Генералом: я сомневался в легкой масштабируемости этой задачи с двумерного случая на трехмерный, но потом убедился, что суть действительно не меняется, хотя математика усложняется. Рассмотрим двумерный случай: ищем окружность минимального радиуса, охватывающую заданный конечный набор кругов. Проведем небольшое исследование, по традиции начинаемое словами: предположим, что задача решена, и минимальная охватывающая окружность построена... В этом месте небольшое лирическое отступление. Два утверждения: 1. На плоскости в общем случае можно провести одну и только одну окружность, касающуюся трех данных (окружность Апполония, ОА) так, чтобы все три данные оказались внутри нее (в дальнейшем, кроме оговоренного, под "касанием" я буду понимать именно такое касание). Иногда такую окружность провести невозможно (вот пример: О о О ), но такие случаи нас волновать не будут, так как они охватываются пунктом 2. 2. Если даны две окружности, то можно провести много окружностей, касающихся их, но только одна при этом будет охватывать их обе с минимальным радиусом ее центр лежит на отрезке, соединяющем центры. ... Охватывающий круг, будучи уже построен, должен либо а) касаться трех (или больше) кругов из данного набора; либо б) касаться только двух, имея при этом минимальный возможный радиус. Первое довольно очевидно, а во втором убедиться можно, представив себе круг неминимального радиуса, касающийся лишь двух кругов - очевидно, его можно уменьшить. Итак, алгоритм решения состоит в следующем. 1. Провести полный перебор всех троек кругов. На каждую тройку натягивать касающуся их окружность , после чего перебором по всем оставшимся кругам смотреть, попадают ли они внутрь нее. Из всех таких окружностей ищем окружность с минимальным радиусом. (Для оптимизации вычислений эти две проверки лучше переставить местами: сначала проверять радиус на минимальность - но это лирика). 2. Найти два максимально отстоящие (дальними точками) круга, натянуть на них минимальную окружность и проверить, охватываются ли все остальные круги этой окружностью. Если да, то сравнить с радиусом, полученном в п.1 и выбрать минимальный. По сути, тут два решения: одно - klem4'овское, только с добавленной проверкой на включение, второе - Бравого Генерала, с тем же самым дополнением. Все! Казалось бы... Но действительно ли все? Теоретически - да. А практически.. Выполнить п.2 сложности не представляет - klem4 уже сделал это. А вот п.1.. Хотя ОА принципиально и находима - этого достаточно для математика, для программера этого мало. Надо указать конкретный способ ее найти. Именно это и тормозило меня с самого начала: хотя описанные выше два пункта алгоритма нащупать было несложно, практический способ постороения ОА мне не давался. В указанной ссылке (см. мои предыдущие посты) способ построения геометрический, реализовать его в коде довольно сложно с моей точки зрения. Поэтому я продолжал думать.. Довольно долго все равно все мои усилия были вокруг простой геометрии типа циркулем и линейкой, хотя я понимал, что без инверсии тут не обойтись. В конце концов я на нее решился. Все оказалось не так уж и страшно Преобразование инверсии, как известно, переводит окружность в окружность, при этом сохраняя касание. Да, конечно - прямо то, что нужно! Только зачем? Зачем переводить окружности в другие? чем другие лучше? А вот чем. Когда я написал уравнения, оказалось, что возможно провести одну инверсию, которая переведет три заданных окружности в три окружности одного заданного диаметра! Внизу, если останется время, приведу подтвеждающие выкладки. Итак, общее правило такое: 1. По трем выбранным кругам (центры и радиусы) находим параметры (центр и радиус) того самого преобразования инверсии, которое переводит эти три окружности в три одинаковые. 2. Произвести инверсию. 3. Построить окружность, касающуюся трех полученных образов. Для этого просто строим окружность, проходящую через их центры, а потом увеличиваем ее радиус на величину радиуса образов. 4. Проводим обратную инверсию (то есть вторично применяем ее). Полученный образ построенной в п.3 окружности - это искомая кружность, касающаяся трех данных. Просто? Не совсем. Но и это еще не все. Необходимо одно уточнение.. Дело в том, что, переводя окружность в окружность, инверсия не переводит центр в центр. Поэтому реально нужно инвертировать две точки окружности, лежащие на луче, проходящем из центра инверсии через центр инвертируемой окружности, а потом взять середину отрезка между ними - это будет центр инвертированной окружности. Вот теперь, кажется, все.. Ах, да! не все.. Осталось добавить, что, как показывают выкладки, инверсия применяется в трехмерном случае (теперь уже к четырем сферам) вполне аналогично, хотя вычисления усложняются. Далее, в 3D придется рассматривать не два случая, а три: 1. Касание четырех шаров. 2. Минимальное касание трех шаров. 3. Минимальное касание двух шаров. Строгости ради, сюда (а также выше) надо добавить еще и случай, когда одна из данных сфер уже охватывает все остальные, но он настолько тривиален, что лень было упоминать. Хотя в программном продукте он должен быть учтен, разумеется. Теперь совесм все!! Ну, как вам решеньеце? Мне почему-то кажется, что с набором из сотни шаров современный Р4 за пару часов справится. Но о тысяче не стоит и говорить.. Хотя, простор для оптимизации тут немеряный.. Мужики (дамы так и не присоединились к обсуждению), не судите строго - я выложу вычисления on request - ладно? И так уже больше получаса пишу.. Всем спасибо за внимание! Жду критики (или опровержений ) P.S. Перечитал - и обнаружил в своих рассуждениях ошибку, которая может иметь принципиальное значение. Или, по крайней мере, еще усложнит алгоритм.. Кто еще заметил? -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Lapp |
Сообщение
#28
|
Уникум Группа: Пользователи Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: 159 |
Похоже, я изрядно напугал народ своим ответом...
Неужели никого не заинтересовало? Все так активно говорили.. Мне кажется, там еще полно материала для обсуждения. Не исключаю, что все же может найтись более простое решение. И зачинатель темы куда-то делся.. Ау-у! -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Текстовая версия | 21.12.2024 20:02 |