Скорость нахождения точек пересечения

Автор Тема: Скорость нахождения точек пересечения  (Прочитано 9346 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 29
  • Карма: 0
Добрый вечер. Для нахождения точек пересечения проекции на плоскость полилинии с другими линиями использую метод IntersectWith(), все работает штатно. Однако, в моем конкретном случае линий 450 штук. К примеру, в цикле метод вызывается 450 раз, время выполнения около 50 сек. Из всех линий полилиния пересекает всего штук 20. Каким образом можно увеличить скорость обработки линий?
Вопрос 2.
Необходимо найти все точки пересечения проекций на плоскость полилиний, на каждой создать вершину . Пока добавляю все линии в лист, далее двумя циклами перебираю все линии и нахожу точки пересечений добавляю вершины. Но тут скорость обработки такая, что можно вообще на полчасика пойти погулять.... правильно ли использовать такое количество циклов?

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Возможно быстрей будет искать сначала пересечение габаритов линий. Погуглите тему RTree

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
К примеру, в цикле метод вызывается 450 раз, время выполнения около 50 сек.
Это очень много. Что-то в алгоритме не то. Без кода непонятно в чем проблема.
Вопрос 2.
Один вопрос - одна тема.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Попутно: пересечения линий и дуг в плоскости элементарно вычисляются чисто математически  - школьная геометрия. По моему опыту чистая математика дает ускорение раз в 10 по сравнению с простыми вызовами API. Плюс к тому можно загнать все данные в самодельные классы и обрабатывать параллельно.

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

  • ADN OPEN
  • Сообщений: 29
  • Карма: 0
Код - C# [Выбрать]
  1. Plane planeXoy = new Plane(
  2. Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d.Origin,
  3. Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis
  4. );
  5. Point3dCollection points = new Point3dCollection();
  6. Point3dCollection intersectionPoints = new Point3dCollection();
  7.                      
  8.  
  9. for (int i = 0; i < ListOfAllPolyline.Count; i++)
  10. {
  11.       Point3dCollection points = new Point3dCollection();
  12.  
  13.       c1.IntersectWith(ListOfAllPolyline[i], Intersect.OnBothOperands, planeXoy, points, IntPtr.Zero, IntPtr.Zero);
  14.       if (points.Count != 0)
  15.       {
  16.             ListOfPolyline.Add(ListOfAllPolyline[i]);
  17.             foreach (Point3d Point_ in points)
  18.             {
  19.                   var xline = new Xline();
  20.                   xline.BasePoint = Point_;
  21.                   xline.UnitDir = Vector3d.ZAxis;
  22.                   c1.IntersectWith(xline, Intersect.OnBothOperands, planeXoy, intersectionPoints, IntPtr.Zero, IntPtr.Zero);
  23.             }                              
  24.  
  25.       }
  26. }

При отладке основное время занимает вот этот код.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Podushkin,
Это не код, а огрызок кода. Для того, чтобы оценить производительность этого кода нужно понять порядок количества вершин у этих полилиний и возможность дуговых сегментов у них.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 29
  • Карма: 0
Код - C# [Выбрать]
  1.  public void iterateObjects( List <string> b)
  2.         {
  3.            
  4.             Database db = HostApplicationServices.WorkingDatabase;
  5.             Document acDoc = acad.DocumentManager.MdiActiveDocument;
  6.             Editor ed = acDoc.Editor;
  7.  
  8.             using (DocumentLock docLock = acDoc.LockDocument())
  9.             {
  10.                
  11.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  12.                 {
  13.                  
  14.                     BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
  15.  
  16.                     Polyline3d c1 = new Polyline3d();
  17.                     Polyline c2 = new Polyline();
  18.                     List<Polyline> ListOfPolyline = new List<Polyline>();
  19.                     List<Polyline> ListOfAllPolyline = new List<Polyline>();
  20.  
  21.                     PromptSelectionResult selectionRes = ed.SelectImplied();
  22.                     if (selectionRes.Status == PromptStatus.Error)
  23.                     {
  24.                         PromptSelectionOptions selectionOpts = new PromptSelectionOptions();
  25.                      
  26.                         selectionOpts.SingleOnly = true;
  27.                         selectionRes = ed.GetSelection(selectionOpts);
  28.                         ed.WriteMessage(selectionRes.ToString());
  29.                     }
  30.                     else
  31.                     {
  32.                         ed.SetImpliedSelection(new ObjectId[0]);
  33.                     }
  34.                     if (selectionRes.Status == PromptStatus.OK)
  35.                     {
  36.                         try
  37.                         {
  38.                             objIds = selectionRes.Value.GetObjectIds();
  39.                             foreach (ObjectId objId in objIds)
  40.                             {
  41.                                 DBObject targetobj = (DBObject)tr.GetObject(objId, OpenMode.ForWrite);
  42.                                 c1 = targetobj as Polyline3d;
  43.                             }
  44.                         }
  45.  
  46.                         catch (Autodesk.AutoCAD.Runtime.Exception ex)
  47.                         {
  48.                             ed.WriteMessage(ex.Message);
  49.                             tr.Abort();
  50.                         }
  51.  
  52.                     }
  53.  
  54.                     if(c1.Id != ObjectId.Null)
  55.                     {
  56.                         // "пробегаем" по всем объектам в пространстве модели
  57.                         foreach (ObjectId id in ms)
  58.                         {
  59.                            
  60.                             Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
  61.                             foreach (string a in b)
  62.                             {
  63.                                 if (entity.Layer == a) //ИИ_Горизонтали_М
  64.                                 {
  65.                                     if (entity.GetType() == typeof(Polyline))
  66.                                     {
  67.                                        
  68.                                         acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n",
  69.                                         entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString()));
  70.                                         c2 = entity as Polyline;
  71.                                         ListOfAllPolyline.Add(c2);
  72.                                     }
  73.                                 }
  74.                             }
  75.                                
  76.  
  77.                         }
  78.                         Plane planeXoy = new Plane(
  79.                         Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d.Origin,
  80.                         Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis
  81.                         );
  82.                         Point3dCollection intersectionPoints = new Point3dCollection();
  83.                      
  84.  
  85.                         for (int i = 0; i < ListOfAllPolyline.Count; i++)
  86.                         {
  87.                             Point3dCollection points = new Point3dCollection();
  88.                          
  89.                             c1.IntersectWith(ListOfAllPolyline[i], Intersect.OnBothOperands, planeXoy, points, IntPtr.Zero, IntPtr.Zero);
  90.                             if (points.Count != 0)
  91.                             {
  92.                                 ListOfPolyline.Add(ListOfAllPolyline[i]);
  93.                                 foreach (Point3d Point_ in points)
  94.                                 {
  95.                                     var xline = new Xline();
  96.                                     xline.BasePoint = Point_;
  97.                                     xline.UnitDir = Vector3d.ZAxis;
  98.                                     c1.IntersectWith(xline, Intersect.OnBothOperands, planeXoy, intersectionPoints, IntPtr.Zero, IntPtr.Zero);
  99.                                 }
  100.  
  101.                             }
  102.                         }
  103.                        
  104.                         List<double> intersectionDistances = new List<double>();
  105.                      
  106.                         foreach (Point3d intersectionPoint in intersectionPoints)
  107.                         {
  108.  
  109.                             try
  110.                             {
  111.                                 intersectionDistances.Add(c1.GetParameterAtPoint(intersectionPoint));
  112.                             }
  113.                             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  114.                             {
  115.                                 continue;
  116.                             }
  117.  
  118.                         }
  119.  
  120.  
  121.                        
  122.                         intersectionDistances.Insert(0, c1.StartParam);
  123.                         intersectionDistances.Add(c1.EndParam);
  124.  
  125.                        
  126.                         intersectionDistances.Sort();
  127.  
  128.                        
  129.                         DBObjectCollection splitCurves = c1.GetSplitCurves(new DoubleCollection(intersectionDistances.ToArray()));
  130.  
  131.                        
  132.                         IList<Entity> splitEntities = splitCurves.OfType<Entity>().ToList();
  133.                         Polyline3d poly = new Polyline3d();
  134.                         if (splitEntities.Count > 0)
  135.                         {
  136.                             using (BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead))
  137.                             {
  138.                                 using (BlockTableRecord blockTableRecord = (BlockTableRecord)tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite))
  139.                                 {
  140.                                    
  141.                                     Entity polyline = splitEntities[0];
  142.  
  143.                                     polyline.SetDatabaseDefaults();
  144.                                  
  145.                                     splitEntities.RemoveAt(0);
  146.  
  147.                                     if (splitEntities.Count > 0)
  148.                                     {
  149.                                        
  150.                                         polyline.JoinEntities(splitEntities.ToArray());
  151.  
  152.                                     }
  153.  
  154.                                     blockTableRecord.AppendEntity(polyline);
  155.  
  156.                                     tr.AddNewlyCreatedDBObject(polyline, true);
  157.                                     poly = polyline as Polyline3d;
  158.                                 }
  159.                             }
  160.                         }
  161.                         Entity entity2 = (Entity)tr.GetObject(c1.Id, OpenMode.ForWrite, false, true);
  162.                         entity2.Erase();
  163.                         tr.Commit();
  164.                        
  165.                     }
  166.                    
  167.                    
  168.                 }
  169.             }
  170.            
  171.         }

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Для начала отсеки те горизонтали, у которых BoundingBox не имеет пересечения с BoundingBox линии, пересечение с которой ты ищешь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 29
  • Карма: 0
Спасибо

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Podushkin,
Следующее. Хотя код и достаточно путанный, но мне кажется что я сумел понять, что ты находишь пересечение Polyline3d со всеми Polyline определенного слоя и в точках пересечения хочешь добавить вершины в Polyline3d. Если я прав, то тебе незачем сначала эту Polyline3d расчленять на сегменты, а затем объединять обратно, удалять старую Polyline3d и добавлять новую. Достаточно добавить новые вершины при помощи метода Polyline3d.InsertVertexAt в старую Polyline3d.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 29
  • Карма: 0
Да, Вы правы. Переделаю.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну и если приложишь dwg-файл, на котором тестировал, то возможно я смогу подсказать еще варианты для оптимизации.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 29
  • Карма: 0
Александр, можно ссылку на пример работы с BoundingBox? Как я понял это некий контейнер (контур), и для начала необходимо найти количество объектов, которые входят в этот контур?

Отмечено как Решение Podushkin 28-06-2021, 22:08:23

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Entity.GeometricExtents
Нужно найти его для Polyline3d и для всех Polyline горизонталей. После это отбираешь только те Polyline у которых GeometricExtents пересекаются с GeometricExtents твоей Polyline3d. Проверять пересечение нужно по X и Y игнорируя Z.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение