Сегмент полилинии по точке

Автор Тема: Сегмент полилинии по точке  (Прочитано 10253 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет. Задача вроде тривиальная, но не тут-то было ))
В общем - хочу одним выбором объединить два действия - выбрать полилинию и выбрать сегмент полилинии.
Мои предположения: используем PromptEntityResult и получаем выбранный примитив (полилинию) и точку PickedPoint. По точке определяем сегмент.
Т.к. метода получить сегмент по точке нет, то делаем итерацию по вершинам, получаем сегмент в вершине, проверяем его тип (в моем случае нужна Дуга) и проверяем, что PickedPoint принадлежит сегменту. Ну или рядом. У Kean Walmsley нашел похожую тему и попытался ее "прикрутить" к своим нуждам. Прикладываю один из вариантов моих попыток:
Код - C# [Выбрать]
  1. try
  2. {
  3.     var doc = AcApp.DocumentManager.MdiActiveDocument;
  4.     var db = doc.Database;
  5.     var ed = doc.Editor;
  6.     while (true)
  7.     {
  8.  
  9.  
  10.         var peo = new PromptEntityOptions("\nВыберите дуговой сегмент полилинии: ")
  11.         {
  12.             AllowNone = false,
  13.             AllowObjectOnLockedLayer = true
  14.         };
  15.         peo.SetRejectMessage("\nНеверный выбор");
  16.         peo.AddAllowedClass(typeof(Polyline), true);
  17.  
  18.         var per = ed.GetEntity(peo);
  19.         if (per.Status != PromptStatus.OK) return;
  20.         var plineId = per.ObjectId;
  21.         var pickedPt = per.PickedPoint;
  22.  
  23.         using (doc.LockDocument())
  24.         {
  25.             using (var tr = db.TransactionManager.StartTransaction())
  26.             {
  27.                 var dbObj = tr.GetObject(plineId, OpenMode.ForRead);
  28.  
  29.                 if (dbObj is Polyline)
  30.                 {
  31.                     var pline = dbObj as Polyline;
  32.                     for (var i = 0; i < pline.NumberOfVertices; i++)
  33.                     {
  34.                         var segType = pline.GetSegmentType(i);
  35.                         if (segType == SegmentType.Arc)
  36.                         {
  37.                             Curve3d segment = pline.GetArcSegmentAt(i);
  38.                             var p = segment.GetClosestPointTo(pickedPt).Point;
  39.  
  40.                             if (segment.IsOn(p))
  41.                             {
  42.                                 pline.UpgradeOpen();
  43.                                 //.......остальной неважный код
  44.                                 break;
  45.                             }
  46.                         }
  47.                     }
  48.                 }
  49.                 tr.Commit();
  50.             }
  51.         }
  52.     }
  53. }
  54. catch (System.Exception exception)
  55. {
  56.     MpExWin.Show(exception);
  57. }
Логично, что код должен работать, но он не работает. Я пробовал различные вариации, в том числе из Tolerance.Global.EqualPoint. Но либо код вообще не работает, либо работает когда курсор в момент выбора находится на соседнем сегменте

Оффлайн bargool

  • ADN Club
  • ***
  • Сообщений: 111
  • Карма: 6
Re: Сегмент полилинии по точке
« Ответ #1 : 23-11-2015, 17:03:16 »
А PromptNestedEntityResult не поможет?
Там у него есть вроде как есть метод GetContainers(), который
Цитировать
Returns an array of object IDs representing the containers of this nested entity
Это так, в порядке быстрого бреда. Правда, это не даст сегмент полилинии, но даст дугу, его составляющую
Алексей

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: Сегмент полилинии по точке
« Ответ #2 : 23-11-2015, 17:15:21 »
Там у него есть вроде как есть метод GetContainers()
Попробовал - при выборе полилинии GetContainers() всегда возвращает пустой список

Оффлайн bargool

  • ADN Club
  • ***
  • Сообщений: 111
  • Карма: 6
Re: Сегмент полилинии по точке
« Ответ #3 : 23-11-2015, 17:18:50 »
Зато можно взять концевые точки полученного элемента, и найти их среди вершин полилинии
Алексей

Отмечено как Решение Александр Пекшев aka Modis 23-11-2015, 17:35:43

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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Сегмент полилинии по точке
« Ответ #4 : 23-11-2015, 17:23:22 »
Находишь ближайшую точку на полилинии. Находишь параметр в этой точке. Находишь по параметру вершину.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: Сегмент полилинии по точке
« Ответ #5 : 23-11-2015, 17:35:36 »
Александр Ривилис, спасибо! Это оно
Как обычно бывает - нужно взглянуть на проблему с другой стороны =)

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Re: Сегмент полилинии по точке
« Ответ #6 : 02-04-2019, 08:20:47 »
Находишь ближайшую точку на полилинии. Находишь параметр в этой точке. Находишь по параметру вершину.

Может это отсюда же.
А как найти ближайшую точку на полилинии в месте выбора полилинии?



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

  • Administrator
  • *****
  • Сообщений: 13898
  • Карма: 1790
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Сегмент полилинии по точке
« Ответ #7 : 02-04-2019, 08:58:50 »
А как найти ближайшую точку на полилинии в месте выбора полилинии?
Воспользуйся методом Curve.GetClosestPointTo
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение