Получить объект Дуги из полилинии

Автор Тема: Получить объект Дуги из полилинии  (Прочитано 7688 раз)

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

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

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Подскажите как лучше всего из объекта
Polyline2d получить объект Arc.
Конечно же только в том
месте, где GetBulgeAt(index) не равно 0

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #1 : 11-09-2017, 21:52:32 »
У себя в коде нашел есть такая штука
Код - C# [Выбрать]
  1. CircularArc2d Arc2d = pl.GetArcSegment2dAt(i);
и из нее надо получить объект Arc


Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Получить объект Дуги из полилинии
« Ответ #2 : 11-09-2017, 21:54:23 »
Ну так осталось только создать дугу: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-EF4D9742-F41F-48E1-BDDC-235069C52176-htm.html
Все нужные параметры - в объекте calc_2d

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #3 : 11-09-2017, 21:58:51 »
А ну все понятно вот это же просто

Код - C# [Выбрать]
  1. Polyline pl;
  2. ...
  3. CircularArc2d arc2d = pl.GetArcSegment2dAt(i);
  4. Arc arc = New Arc(new Point3d(arc.Center.X, arc.Center.Y, 0) ,
  5.                        arc.Radius,
  6.                        arc.StartAngle,
  7.                        arc.EndAngle);
  8.  


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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #4 : 11-09-2017, 22:17:20 »
А ну все понятно вот это же просто
Ну не так всё просто. Посмотри: http://adndevblog.typepad.com/autocad/2012/05/converting-polyline-arc-to-acdbarc-and-vice-versa.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #5 : 11-09-2017, 22:36:11 »
Кстати, самое смешное, что простейший способ получить все дуги и отрезки из полилинии - использовать метод Explode для неё. Ну а взять i-ый элемент из коллекции отрезков и дуг, на которые разваливается полилиния, совсем не проблема. Не забудь только для остальных примитивов, полученных в результате расчленения вызвать метод Dispose(). Думаю что этот метод будет не слишком быстрый и использовать его при массовых вычислениях не стоит.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #6 : 12-09-2017, 18:53:44 »
Все же через explode придется делать
т.к. через GetArcSegment2dAt
StartAngle возвращает ноль, а это ни как ни катит.
 

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #7 : 12-09-2017, 18:56:24 »
Еще вопрос.
Я надеюсь, что набор объектов через explode
вернется в нормальной последовательности?
Т.е. в той последовательноси, в которой
рисовали полилинию.

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #8 : 12-09-2017, 18:58:46 »
Думаю что этот метод будет не слишком быстрый и использовать его при массовых вычислениях не стоит.
В рельной работе полиниий может быть примерно 2 сотни штук
В среднем одна полилиния может содержать 60 отрезков.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #9 : 12-09-2017, 19:00:51 »
Т.е. в той последовательноси, в которой
рисовали полилинию.
Надеюсь. А тебе нужны все дуги из полилинии или только одна конкретная? Если одна, то я могу немного позже предложить другой алгоритм.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #10 : 12-09-2017, 19:01:32 »
В рельной работе полиниий может быть примерно 2 сотни штук
В среднем одна полилиния может содержать 60 отрезков.
Ну это немного для современных PC.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #11 : 12-09-2017, 19:04:34 »
А тебе нужны все дуги из полилинии или только одна конкретная?
Мне нужны все дуги.
Но вреальной работе их не так много
(десятки штук у одной полилинии).

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #12 : 12-09-2017, 19:09:05 »
Причем мне нужно еще немного по хитрому.
К примеру у полилинии я беру дугу.
Но для реальной задчи мне нужны две дуги
(две ее половинки: от начала до середины и от середины до конца)

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #13 : 12-09-2017, 19:13:19 »
Но для реальной задчи мне нужны две дуги
(две ее половинки: от начала до середины и от середины до конца)
А вот это уже другая задача.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #14 : 12-09-2017, 19:19:20 »
У меня уже написана задача, которая возвращает массив из трёх точек

Код - vb.net [Выбрать]
  1. Dim arc As CAD_GEO.CircularArc2d = pl.GetArcSegment2dAt(indexNode)
  2. Dim Count As Integer = 3
  3. Dim p2d() = arc.GetSamplePoints(Count)

 (начало середина и конец). Осталось только по этим
трем точкам и точке центра окружности построить две дуги.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #15 : 12-09-2017, 19:22:29 »
Осталось только по этим
трем точкам и точке центра окружности построить две дуги.
По трём точкам однозначно строится одна дуга. Про центр и другую дугу я не понял.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #16 : 12-09-2017, 19:26:36 »
Вот есть конструктор дуги через нормаль (vector3d)
Arc(Point3d, Vector3, Double , Double)
Может его использовать?


Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #17 : 12-09-2017, 19:27:39 »
Нормаль в конструкторе тут какую роль играет?
Если эта нормаль указывает вектор от центра до точки на кривой
дуги и повернет мне дугу как надо то будет хорошо.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #18 : 12-09-2017, 19:47:46 »
Это решение твоей основной задачи - получение всех дуг из полилинии:

Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(Rivilis.PlineArcToArc))]
  10.  
  11. #pragma warning disable CS0618
  12.  
  13. namespace Rivilis
  14. {
  15.   public class PlineArcToArc
  16.   {
  17.     public static Arc GetArcFromGeArc3d(CircularArc3d arc3d)
  18.     {
  19.       Arc arc = null;
  20.       Point3d center = arc3d.Center;
  21.       Vector3d normal = arc3d.Normal;
  22.       Vector3d refVec = arc3d.ReferenceVector;
  23.       using (Plane plane = new Plane(center, normal))
  24.       {
  25.         double ang = refVec.AngleOnPlane(plane);
  26.         arc = new Arc(center, normal, arc3d.Radius,
  27.            arc3d.StartAngle + ang, arc3d.EndAngle + ang);
  28.       }
  29.       return arc;
  30.     }
  31.     [CommandMethod("PArc2Arc")]
  32.     public void PArc2Arc()
  33.     {
  34.       Document doc = Application.DocumentManager.MdiActiveDocument;
  35.       if (doc == null) return;
  36.       Editor ed = doc.Editor;
  37.       PromptEntityOptions peOpt =
  38.         new PromptEntityOptions("\nВыберите полилинию с дугами: ");
  39.       peOpt.SetRejectMessage("Это не полилиния!");
  40.       peOpt.AddAllowedClass(typeof(Polyline), false);
  41.       PromptEntityResult peRes = ed.GetEntity(peOpt);
  42.       if (peRes.Status != PromptStatus.OK) return;
  43.       using (Polyline pl = peRes.ObjectId.Open(OpenMode.ForRead) as Polyline)
  44.       {
  45.         for (int i = 0; i < pl.NumberOfVertices; i++)
  46.         {
  47.           if (pl.GetSegmentType(i) == SegmentType.Arc)
  48.           {
  49.             using (CircularArc3d arc3d = pl.GetArcSegmentAt(i))
  50.             {
  51.               using (Arc arc = GetArcFromGeArc3d(arc3d))
  52.               {
  53.                 using (BlockTableRecord btr = pl.BlockId.Open(OpenMode.ForWrite) as BlockTableRecord)
  54.                 {
  55.                   btr.AppendEntity(arc);
  56.                 }
  57.               }
  58.             }
  59.           }
  60.         }
  61.       }
  62.     }
  63.   }
  64. }

Идея в том, что следует использовать GetArcSegmentAt, а не GetArcSegment2dAt
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #19 : 12-09-2017, 20:19:13 »
Если без using буду использовать объект CircularArc3d,
то для него Dispose тоже не зыбыть сделать?


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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #20 : 12-09-2017, 20:22:22 »
Если без using буду использовать объект CircularArc3d,
то для него Dispose тоже не зыбыть сделать?
Неплохо бы для избежания утечки памяти.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Алексей (IdeaSoft) 12-09-2017, 21:10:17

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Получить объект Дуги из полилинии
« Ответ #21 : 12-09-2017, 20:30:07 »
А вот код с разбиением дуги сразу на две штуки:

Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(Rivilis.PlineArcToArc))]
  10.  
  11. #pragma warning disable CS0618
  12.  
  13. namespace Rivilis
  14. {
  15.   public class PlineArcToArc
  16.   {
  17.     public static bool DivideArc2(Arc arc, out Arc arc1, out Arc arc2)
  18.     {
  19.       arc1 = arc2 = null;
  20.       DoubleCollection parms = new DoubleCollection();
  21.       parms.Add(arc.StartParam);
  22.       parms.Add((arc.StartParam + arc.EndParam) * 0.5);
  23.       parms.Add(arc.EndParam);
  24.       DBObjectCollection dbobjs = arc.GetSplitCurves(parms);
  25.       if (dbobjs.Count == 2)
  26.       {
  27.         arc1 = dbobjs[0] as Arc;
  28.         arc2 = dbobjs[1] as Arc;
  29.         return true;
  30.       }
  31.       return false;
  32.     }
  33.     public static CircularArc3d GetGeArc3dFromArc(Arc arc)
  34.     {
  35.       CircularArc3d arc3d =
  36.         new CircularArc3d(
  37.           arc.Center,
  38.           arc.Normal,
  39.           arc.Normal.GetPerpendicularVector(),
  40.           arc.Radius,
  41.           arc.StartAngle,
  42.           arc.EndAngle);
  43.       return arc3d;
  44.     }
  45.     public static Arc GetArcFromGeArc3d(CircularArc3d arc3d)
  46.     {
  47.       Arc arc = null;
  48.       Point3d center = arc3d.Center;
  49.       Vector3d normal = arc3d.Normal;
  50.       Vector3d refVec = arc3d.ReferenceVector;
  51.       using (Plane plane = new Plane(center, normal))
  52.       {
  53.         double ang = refVec.AngleOnPlane(plane);
  54.         arc = new Arc(center, normal, arc3d.Radius,
  55.            arc3d.StartAngle + ang, arc3d.EndAngle + ang);
  56.       }
  57.       return arc;
  58.     }
  59.     [CommandMethod("PArc2Arc2")]
  60.     public void PArc2Arc2()
  61.     {
  62.       Document doc = Application.DocumentManager.MdiActiveDocument;
  63.       if (doc == null) return;
  64.       Editor ed = doc.Editor;
  65.       PromptEntityOptions peOpt =
  66.         new PromptEntityOptions("\nВыберите полилинию с дугами: ");
  67.       peOpt.SetRejectMessage("Это не полилиния!");
  68.       peOpt.AddAllowedClass(typeof(Polyline), false);
  69.       PromptEntityResult peRes = ed.GetEntity(peOpt);
  70.       if (peRes.Status != PromptStatus.OK) return;
  71.       using (Polyline pl = peRes.ObjectId.Open(OpenMode.ForRead) as Polyline)
  72.       {
  73.         for (int i = 0; i < pl.NumberOfVertices; i++)
  74.         {
  75.           if (pl.GetSegmentType(i) == SegmentType.Arc)
  76.           {
  77.             using (CircularArc3d arc3d = pl.GetArcSegmentAt(i))
  78.             {
  79.               using (Arc arc = GetArcFromGeArc3d(arc3d))
  80.               {
  81.                 Arc arc1 = null, arc2 = null;
  82.                 if (DivideArc2(arc, out arc1, out arc2))
  83.                 {
  84.                   using (arc1) using (arc2)
  85.                   using (BlockTableRecord btr = pl.BlockId.Open(OpenMode.ForWrite) as BlockTableRecord)
  86.                   {
  87.                     btr.AppendEntity(arc1);
  88.                     btr.AppendEntity(arc2);
  89.                   }
  90.                 }
  91.               }
  92.             }
  93.           }
  94.         }
  95.       }
  96.     }
  97.   }
  98. }

Возможны и другие варианты решения.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей (IdeaSoft)Автор темы

  • ADN
  • *
  • Сообщений: 1188
  • Карма: 9
    • idea-soft.ru
  • Skype: makar_govorun
Re: Получить объект Дуги из полилинии
« Ответ #22 : 12-09-2017, 21:10:41 »
Спасбо большое супер то что нужно!