Узнать точку пересечения полилинии и блока c#

Автор Тема: Узнать точку пересечения полилинии и блока c#  (Прочитано 18928 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн DenisАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
Здравствуйте.
Извиняюсь,если кто-то эту тему уже поднимал.

У меня есть набор полилиний, которые стыкуются с блоками,хотелось бы узнать как определить какой конкретно блок пересекается с полилинией для того,чтобы вытащить из него имя.
Подскажите пожалуйста,откуда начать копать?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Приветствую на форуме!
которые стыкуются с блоками
пересекается с полилинией
Так стыкуются или пересекаются?
Если не вдаваться в детали постановки, то можно использовать метод Entity.IntersectWith для попарной проверки на пересечение полилинии и (габаритного контейнера) вставки блока.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн DenisАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
Правильнее будет все-таки стыкуется.Буду аккуратнее в терминологии.В приложении файл,там есть полилиния и два блока на концах.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Правильнее будет все-таки стыкуется.
В том виде как нарисовано в dwg-файле я не вижу способа обрабатывать информацию. Конечные точки полилинии не касаются блоков (т.е. имеется весьма ощутимый зазор). И скорее всего Entity.IntersectWith ничего не даст.
Думаю, что вопрос нужно решать организационно. А именно конечная точка полилинии должна совпадать с точной вставки блока с заданной точностью. Тогда задача упрощается и ускоряется как минимум на порядок.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн DenisАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
То есть та линия, которая выходит из блока, и стыкуется с полилинией в расчет не идет? Получается,что полилинию надо доводить до контура блока и только потом использовать Intersectwith? И костыль по типу координаты одного конца полилинии совпадает с координатами конца линии из блока не пройдет?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
И костыль по типу координаты одного конца полилинии совпадает с координатами конца линии из блока не пройдет?
Всё зависит постановки задачи. В общем случае (если нет ограничений на типы примитивов в блоке, масштаб по осям вставки блока и т.д.), то мягко говоря будет не слишком просто вычислить координаты линии, находящейся в блоке. И еще придётся пройтись по всем вставкам блоков, найти в них все линии, найти для каждой линии характерные точки и преобразовать в их в МСК, а затем их сравнивать с координатами вершин всех полилиний.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн DenisАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
Спасибо за ответ.
В продолжение решил попробовать написать код.Вопрос следующий: я получил все блоки как block table record, как проверить,что они пересекаются.Я просто полный новичок в этом и такое api меня пугает.
Заранее спасибо за подсказки!

Код - C# [Выбрать]
  1. using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  2.             {
  3.                
  4.                 BlockTable acBlkTble;
  5.                 acBlkTble = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
  6.                 foreach (ObjectId objId in acBlkTble)
  7.                 {
  8.                     BlockTableRecord btr;
  9.                     btr = acTrans.GetObject(objId, OpenMode.ForRead) as BlockTableRecord;
  10.                     acDoc.Editor.WriteMessage("\n" + btr.Name);
  11.                     list_bl.Add(btr);
  12.                 }
  13.                 acTrans.Commit();
  14.             }
  15.  
  16.  
  17.                         foreach (Entity block in list_bl)
  18.                         {
  19.                             Point3dCollection pts = new Point3dCollection();
  20.                             block.IntersectWith(poly,Intersect.ExtendArgument,pts,0,0);
  21.  
  22.                             if (pts.Count != 0)
  23.                             {
  24.                                 sheet1.addCell(new Label(3, 1, block.BlockName));
  25.                             }
  26.                         }
« Последнее редактирование: 28-06-2015, 21:25:41 от Александр Ривилис »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
1. Начни с того, что прочитай мою подпись по поводу форматирования кода на форуме.
2. Я вижу какой-то совершенно непонятный для меня обрывок кода.
3. Проверку на пересечение нужно делать не для BlockTableRecord, а для BlockReference (т.е. для вставок блоков).
4. Один из вариантов - использование метода BlokReference.Explode и проверка на пересечение с коллекцией полученных примитивов. Есть правда ограничение, когда масштабные коэффициенты по X,Y,Z не равны.
« Последнее редактирование: 28-06-2015, 21:27:58 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Тут в общем случае все достаточно не просто. По хорошему надо проиндексировать все габаритные контейнеры необходимых блоков (BoundingBox), после чего вытянуть в сторону удлинения все (или только нужные) классы от Curve и проверять на принадлежность крайним точка индексов блоков, после чего уже запускать функцию сверки (касается? не касается?). Но и это годиться только для не сильно насыщенных чертежей - если тысячи линий надо проверить к тысячам блоков (по сути проверяется каждая к каждой), то тогда неплохо бы изучить R-деревья (писать реализацию не обязательно - готовые реализации в сети я точно видел) и индексировать по ним. В любом случае задачу следует хорошенько конкретизировать перед "кодовством".
з.ы. есть еще api автокада по выбору в заданных областях - но они работают только с тем что видно на экране и то в определенном масштабе - в общем не надежно.

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
http://sourceforge.net/projects/cspatialindexrt/
каноничная реализация...

Оффлайн DenisАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
Спасибо за ответы! Про код извиняюсь,надеюсь,что в следующий раз справлюсь)

Задачу я реализовал.Нашел точки пересечения блоков и полилиний.И это даже работает.Единственное,что сейчас все работает тупо с перебором блоков.Буду искать способ ускорить программу,возможно при помощи R-деревьев.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Единственное,что сейчас все работает тупо с перебором блоков
Перебирать придётся в любом случае, но Дима_ подсказал как можно перебирать быстрее - пройтись по всем вставкам блоков в чертеже и сохранить в коллекции их BoundigBox'ы. Это может очень значительно ускорить процесс. Ну а следующая оптимизация - деревья.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн DenisАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 63
  • Карма: 2
Сейчас я просто добавляю BlockReferences в List. Потом делаю IntersectWith. Это не то же самое,что BoundingBoxes?
Буду разбираться с R-trees.Надеюсь разберусь.
Спасибо за подсказки!

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Это не то же самое,что BoundingBoxes?
Нет. Вы к каждому блоку запускаете долгую проверку на пересечение - а ее нужно запускать если только точка находиться в габаритах блока. С деревьями можно особо и не разбираться - а нагуглить готовые.
На всякий случай - если вдруг программный проект связан с SQL DB- практически во всех СУБД есть пространственные индексы основанные на r-деревьях.
з.ы. вот только в автокаде их почему-то нет?? Хотя "внутри" они скорее всего таки используются.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Это не то же самое,что BoundingBoxes?
Нет. BoundingBox (точнее Entity.GeometricExtents) позволяет получить параллелепипед со сторонами параллельными осям X Y Z мировой системы координат (МСК), в который вписывается (полностью влезает) примитив.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение