Сообщество программистов Autodesk в СНГ
ADN Club => AutoCAD .NET API => Тема начата: Алексей (IdeaSoft) от 18-06-2014, 21:33:13
-
Использую в работе .NET функцию Document.Editor.SelectCrossingPolygon выбора набора примитивов, которые пересекаются с набором точек. Набор точек беру из 2d-полилинии. Формирую набор Point3dCollection (координата Z=0 у всех точек). Примитивы, которые должны пересекаться тоже плоские–2D. Набор примитивов возвращается все нормально.
Но те примитивы которые находятся за пределами видимой области видового экрана монитора,
почему-то не попадают в набор. Ранее, когда использовал ActiveX такая же ситуация.
-
И именно так и должно быть. Так сложилось исторически еще во времена AutoCAD для DOS. Вариантов только два:
1) перед вызовом Editor.SelectCrossingPolygon делать видимым всё, что нужно на экране.
2) не пользоваться Editor.SelectCrossingPolygon и делать всё тоже самое другими методами.
P.S.: Это касается всех методов Editor.SelectXXX (кроме Editor.SelectAll)
-
Да мне так и приходится делать "зумировать все" и только тогда.
Единственное, что пользователю вот эти "зумы" не очень нравятся.
Видимо так было задумано еще в DOS что экономить вычислительные ресурсы.
Но сейчас уже не те времена. Может сообщить разработчикам
что бы доработали функции семейства SelectionXXX.
Можно даже добавить специальный аргумент,
который бы управлял режимами работы функций.
-
Может сообщить разработчикам
что бы доработали функции семейства SelectionXXX
эх, наивность, "молодо-зелено"... :) С тем же успехом можно писать письма "на деревню дедушке".
-
Тогда буду писать алгоритм с использованием функции IntersectWith
При большом количестве перебора примитивов это будет работать медленно.
В этом случае мне нужно будет индексировать размещение объектов на плоскости.
Тогда в набор будет попадать небольшое количество объектов, которые рядом с этой полилинией,
сократится размер цикла для проверки пересечения и будет работать быстрее.
-
"на деревню дедушке".
А почему так считаешь? Я напротив думаю, что Autodesk как и
любой производитель ПО заинтересован в улучшении своих продуктов
и примет во внимания наши пожелания.
-
Этой "особенности" 100 лет в обед...
-
А почему так считаешь?
Имею некоторую практику общения по данной части.
Я напротив думаю, что Autodesk как и
любой производитель ПО заинтересован в улучшении своих продуктов
и примет во внимания наши пожелания.
Думать-то ты можешь, только практика не всегда сходится с теорией. Есть ещё и такая вещь как "планы манагеров". С качеством ПО это, как правило, не имеет ничего общего.
Никто тебе не запрещает, если хочешь - пиши им. Посмотришь результат.
-
1. Алгоритм переделывать не будут. Уверен на 100%. Объясню почему. Алгоритм использует экранное представление примитивов и соответственно ограничен размерами экрана (или чуть больше). Такой алгоритм существенно (возможно на несколько порядков) быстрее, чем сканирование всего пространства Модели/Листа. По поводу изменения алгоритма уже обращались - ответ читай выше.
2. Можно конечно придумать массу разных алгоритмов, ускоряющих работу, но перебрать все примитивы пространства Модели/Листа всё равно придется. :( Например можно проверять пересечение BoundingBox. Кстати, IntersectWith работает далеко не со всеми примитивами. Для некоторых типов примитивов (например, BlockReference) он находит точки пересечения не с примитивами блока, а с его BoundingBox
-
Я напротив думаю, что Autodesk как и
любой производитель ПО заинтересован в улучшении своих продуктов
и примет во внимания наши пожелания.
Да, но не в данном случае. Эта особенность была документирована изначально и на изменение работы алгоритма они не пойдут.
-
Но в моей задаче использование IntersectWith возможно, т.к. скорее блоками пока
мне не придется пользоваться.
А если и придется работать с блоками, то нужно будет "залезать" внутрь базы блока.
Правда внутри базы блока тоже есть проблема ведь координаты примитивов
хранятся, вроде как, относительно точки вставки блока.
Нужно будет клонировать примитивы блока (причем один раз для описателя блока)
со сдвигом относительно базовой точки каждого экземпляра блока.
-
Эта особенность была документирована изначально
Да у меня были догадки, что разработчики эту задачу решили в области вывода
контекста устройства графической карты - это действительно быстрое решение.
-
Правда внутри базы блока тоже есть проблема ведь координаты примитивов
хранятся, вроде как, относительно точки вставки блока.
Нужно будет клонировать примитивы блока (причем один раз для описателя блока)
со сдвигом относительно базовой точки каждого экземпляра блока.
Можно использовать метод Explode - в большинстве случаев он должен помочь.
-
Можно использовать метод Explode
Да-да! Точняк! Про Explode совсем забыл вроде он тоже хорош! Подойдет!
-
Да у меня были догадки, что разработчики эту задачу решили в области вывода
контекста устройства графической карты - это действительно быстрое решение.
Не совсем так. Это не уровень карты. Есть промежуточный уровень, когда все примитивы AutoCAD (в пределах области видимости) проецируются на плоскость изображения и мы имеем плоские (но векторные, а не растровые) образы, связанные с оригинальными примитивами. А вот найти пересечение на плоскости ограниченной размерами экрана конечно же на порядок проще.
-
Можно использовать метод Explode
Да-да! Точняк! Про Explode совсем забыл вроде он тоже хорош! Подойдет!
Достаточно недавно обсуждали: http://adn-cis.org/forum/index.php?topic=662.msg2328#msg2328
-
Тогда ясно просто область выборки ограничивается экраном.
Думаю что если область выборки буду ограничивать некоторым "коридором"
полилинии, то тоже выборка будет не большой и пересечения найдутся быстрее,
чем перебирать весь набор примитивов.
-
Для целей поиска пересечений прекрасно подойдёт R-Tree (или другие подобные структуры данных). Искать Spatial Index (http://en.wikipedia.org/wiki/Spatial_database#Spatial_index)
Вот была большая тема (http://forum.dwg.ru/showthread.php?p=1157666&#post1157666), где обсуждали подобную задачу.
-
bargool - индексация требуется если идет многократная проверка (каждой к каждому) например, или если чертеж однозначно "постоянный", при одноразовой проверке - смысла не имеет. Я бы отфильровал сначала по пересечением габаритов, а выбранные уже по факту.
-
А у меня как раз тот случай, когда есть, к примеру, 150 отрезков, которые должны найти пересечение
с 40 000 многоугольниками и отрезками. И проверять пересечение 150 раз с 40 000 объектами - это очень долго будет.
По этому я распределяю объекты по квадратным зонам.
-
По этому я распределяю объекты по квадратным зонам.
Инексируй по прямоугольным зонам. Потом фильтр по ним и непосредственно пересечение.
-
А чем лучше прямоугольники вместо квадратов, то?
-
Тебе не надо разбивать на "сетку" - не будет эффективно (надо подбирать размер ячейки и пр.) - индексацию надо делать непосредственно по габаритам объектов - http://ru.wikipedia.org/wiki/R-tree (http://ru.wikipedia.org/wiki/R-tree), если не осилишь - просто погугли готовый алгоритм.