Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: flaojke от 24-07-2014, 11:52:07

Название: Удаление вершины полилинии
Отправлено: flaojke от 24-07-2014, 11:52:07
Имеется список нескольких точек полилинии и сама полилиния. Необходимо удалить вершины полилинии, которые содержатся в списке deletion. Подскажите, каким способом вообще возможно это реализовать?

Код - C# [Выбрать]
  1. List<Point2d> deletion = new List<Point2d>();
  2.  
  3. var obj = oTr.GetObject(ObjID, OpenMode.ForRead);
  4. Type type = obj.GetType();
  5. string typeName = type.Name;
  6.  
  7. switch (typeName)
  8. case "Polyline":
  9. {
  10.    Polyline PL = (Polyline)obj;
  11. }
  12.  
  13. for (int i = 1; i < 5; i++)
  14.     {
  15.       Point2d pt = PL.GetPoint2dAt(i);
  16.       deletion.Add(pt);
  17.     }
  18.  
  19.  

Пытаюсь реализовать вот так, но никак не получается

Код - C# [Выбрать]
  1. foreach (Point2d P2d in deletion)
  2.         {
  3.            //Команда удаления
  4.         }
Название: Re: Удаление вершины полилинии
Отправлено: Александр Ривилис от 24-07-2014, 12:10:55
Приветствую на форуме! По поводу кода. Очевидно что попытка не правильная. Я правильно понимаю, что тебе просто нужно удалить со второй по пятую вершину полилинии (так как нумерация вершин начинается с нуля)?
Название: Re: Удаление вершины полилинии
Отправлено: flaojke от 24-07-2014, 12:18:48
Да, именно это и нужно сделать. Только там переменные, а не статические значения 3 и 5.
Название: Re: Удаление вершины полилинии
Отправлено: Александр Ривилис от 24-07-2014, 12:21:36
Тогда переформулирую задачу.
Дано:
1) полилиния
2) начальный номер вершины
3) конечный номер вершины
Требуется:
Удалить указанные вершины из полилинии.

Я правильно сформулировал?
Название: Re: Удаление вершины полилинии
Отправлено: flaojke от 24-07-2014, 12:24:16
Да, всё правильно
Название: Re: Удаление вершины полилинии
Отправлено: Андрей Бушман от 24-07-2014, 12:27:10
Цитировать
Приветствую на форуме!
+1
Дано:
1) полилиния
Тогда уж заодно покажите автору как определить тип объекта на основе его идентификатора не получая этот объект. Вы же видите, что он сначала объект получает и только потом смотрит его тип - это негативно влияет на производительность. Фрагмент обозначенного кода не позволяет судить о том, использует ли автор фильтры выбора (если критерии фильтрации достаточно просты) и если да, то насколько грамотно. Возможно в данном случае применение фильтров было бы достаточно разумным решением, поскольку не было бы необходимости в последующей проверке типов.
Название: Re: Удаление вершины полилинии
Отправлено: Александр Ривилис от 24-07-2014, 12:40:30
Тогда уж заодно покажите автору как определить тип объекта на основе его идентификатора не получая этот объект.
А сам? ;)
Да, всё правильно
Попробуй. Не тестировал совсем:
Код - C# [Выбрать]
  1. static void DeleteVertexesFromPolyline(ObjectId id, int iStart, int iEnd)
  2. {
  3.     if (id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(Polyline)))) {
  4.         using (Polyline poly = id.Open(OpenMode.ForWrite) as Polyline) {
  5.             if (iStart >= 0 && iEnd < poly.NumberOfVertices) {
  6.                 if (poly != null) {
  7.                     for (int i = iStart; i < iEnd; i++) {
  8.                         poly.RemoveVertexAt(iStart);
  9.                     }
  10.                 }
  11.             }
  12.         }
  13.     }
  14. }

Название: Re: Удаление вершины полилинии
Отправлено: flaojke от 24-07-2014, 12:41:40
Вы же видите, что он сначала объект получает и только потом смотрит его тип

В программе идёт перебор всех объектов во всех нужных слоях. Данная часть программы находится в цикле перебора всех объектов одного слоя. Только после получения объекта происходит решение, что с ним делать.

Тогда уж заодно покажите автору как определить тип объекта на основе его идентификатора не получая этот объект.

Буду благодарен, за эту информацию.
Название: Re: Удаление вершины полилинии
Отправлено: Александр Ривилис от 24-07-2014, 12:42:55
Буду благодарен, за эту информацию.
Посмотри мой код. Там указан один из вариантов.
Название: Re: Удаление вершины полилинии
Отправлено: flaojke от 24-07-2014, 12:50:53
Посмотри мой код. Там указан один из вариантов.

Большое спасибо, всё работает! Буду дальше разбираться, способ определения посмотрел.

Что-то я упустил "RemoveVertexAt", решил по сложному пути пойти.
Название: Re: Удаление вершины полилинии
Отправлено: Андрей Бушман от 24-07-2014, 12:51:12
А сам?
"а сам" поуши занят. Не разорваться же мне. :)
Код - C# [Выбрать]
  1. static void DeleteVertexesFromPolyline(ObjectId id, int iStart, int iEnd)
  2. {
Первым делом следовало бы проверить id на предмет не равности null, на предмет валидности, и на предмет не удалённости (если нужно обрабатывать только не удалённые объекты). Проверку аргументов вообще следует взять за правило. Не плохо было бы проверять и второй с третьим аргументом (для надёжности кода) например на предмет того, что их значения не меньше нуля и что третий параметр не меньше второго.
Код - C# [Выбрать]
  1. if (poly != null) {
Тут двоякое чувство... Если проверка аргументов прошла успешно, то данная проверка будет лишней (имхо), хотя можно и оставить её, дабы перестраховаться. Однако в случае, если вдруг окажется null, молча пропускать это - на мой взгляд, не самый правильный выбор. Я бы предпочёл либо исключение генерировать, либо сигнализировать об этом путём возвращаемого логического значения, сообщающего об успехе\неудачи операции.
Название: Re: Удаление вершины полилинии
Отправлено: Александр Ривилис от 24-07-2014, 12:55:33
По поводу отсутствующих проверок - согласен. Я показал лишь общий алгоритм и намек на то, что удалять нужно всё время вершину  с одним и тем же номером.
Название: Re: Удаление вершины полилинии
Отправлено: flaojke от 24-07-2014, 12:58:31
Не плохо было бы проверять, что третий параметр не меньше второго.

Удаляться могут точки как с 3 по 5, так и с 8 по 5. Сделана сортировка этих параметров, чтобы первый всегда меньше был.

Возможно ли вставить новую точку полилинии между двумя существующими?
Название: Re: Удаление вершины полилинии
Отправлено: Александр Ривилис от 24-07-2014, 13:00:20
Возможно ли вставить новую точку полилинии между двумя существующими?
Да. Метод Polyline.AddVertexAt
Название: Re: Удаление вершины полилинии
Отправлено: Андрей Бушман от 24-07-2014, 13:00:46
так и с 8 по 5
Ну тогда тебе это
Код - C# [Выбрать]
  1. for (int i = iStart; i < iEnd; i++) {
не подойдёт. Иначе придётся сначала определять min и max. Чем не устроил вариант "с 5 по 8"? Зачем трусы через голову одевать?
Название: Re: Удаление вершины полилинии
Отправлено: Александр Ривилис от 24-07-2014, 13:01:59
Андрей Бушман, он же написал, что сортирует номера.
Название: Re: Удаление вершины полилинии
Отправлено: Андрей Бушман от 24-07-2014, 13:08:19
Андрей Бушман, он же написал, что сортирует номера.
Всё, я не так его понял сначала. :) Однако в коде метода полагаться на то, что вызывающая сторона выполнит сортировку - это очень ненадёжно и неправильно, поскольку всегда существует угроза того, что вызывающая сторона забудет это сделать. Поэтому проверка лишней не будет. Наличие такой проверки повышает уровень независимости кода от внешних факторов.
Название: Re: Удаление вершины полилинии
Отправлено: Александр Ривилис от 24-07-2014, 16:38:35
if (poly != null) {
Спасибо. Эта проверка у меня лишняя (осталась от другого кода) и бессмысленная, т.к. до того вычисляется poly.NumberOfVertices и если poly == null, то мы уже попали в исключение.
Название: Re: Удаление вершины полилинии
Отправлено: Андрей Бушман от 24-07-2014, 16:57:32
Эта проверка у меня лишняя (осталась от другого кода) и бессмысленная, т.к. до того вычисляется poly.NumberOfVertices
Наличие null (или мусора) выяснится ещё раньше, если в коде первым делом выполнять проверку значений полученных параметров, как я и предлагал. :)