ADN Club > ObjectARX
вопрос по сортировке отрисовки объектов с помощью AcDbSortentsTable
(1/1)
begiz:
Добрый день
появилась интересная задачка, с которой уже несколько дней не могу стравится
есть чертеж в котором на 2 слоях расположены объекты типа(строго) AcDbLine
эти объекты пересекаются произвольным образом, т.е. каждая линия может пересекать любое количество других линий
задача по определенной логике отрисовать эти линии в нужной последовательности. принцип логики определения последовательности не важен
на данный момент программа определеяет пересечения 2-х линий в точке и правельно их отрисовывает путем moveAbove/moveBelow
проблема в том что этих пересечений очень много, и поэтому возникло желание собрать всю последовательность в единый массив и за 1 раз их перерисовать через setRelativeDrawOrder
вот собстенно собрать всё в 1 массив и не получается,
потому что, как писал выше, на данный момент данные у меня только на точки пересечения 2 линий и об остальных пересечениях я как бы не знаю.
но так как линии могут пересекаться с лубым количеством других линий, то при добавлении очередной пары линий в массив, может получится что они уже там есть, и можно как то пересортировать его чтобы последовательность не нарушилась
Может ктото сталкивался или может направить как правельно этот вопрос решать?
Александр Ривилис:
begiz,
Я вижу такую схему:
1) При помощи getRelativeDrawOrder получаешь массив AcDbObjectId всего что есть в блоке в том порядке, в котором они есть.
2) Двойной цикл по всем элементам этого массива - сравнение отрезков и swap каждой пары из в массива если не упорядочены.
3) setRelativeDrawOrder
Александр Ривилис:
Альтернативный вариант:
Создать структуру вида
--- Код - C++ [Выбрать] ---struct IDPP { AcDbObjectId id; AcGePoint3d p1, p2;}std::vector<IDPP> idpp;Пройтись по всем отрезкам в блоке и заполнить массив idpp. После этого сортировка (std::sort) с твоей функцией сравнения.
Далее цикл по уже отсортированному idpp для создания AcDbObjectIdArray, используемого в setRelativeDrawOrder
P.S.: Если в функции сравнения еще используется слой, то это придётся отразить в структуре IDPP.
begiz:
всё гениально и просто, спасибо Александр
попробовал 1 вариант.
с 1 прогоном по двоиному циклу не получилось, добавил еще 1 внешний для проверки были ли перестановки и за несколько раз сортировка получилась правельной.
вопрос насчет оптимальности, проверю на большом чертеже
--- Код - C++ [Выбрать] ---bool changes = true;while (changes) { changes = false; for (int i = 0; i < idArray.length(); i++) { for (int j = 0; j < idArray.length(); j++) { if (i == j) continue; if (needSwitchDrawOrder(idArray[i],idArray[j])) //страшная логика { idArray.swap(i,j); changes = true; } } }}
Александр Ривилис:
begiz,
Вместо
--- Код - C++ [Выбрать] ---for (int j = 0; j < idArray.length(); j++)должно быть
--- Код - C++ [Выбрать] ---for (int j = i + 1; j < idArray.length(); j++)Если требуется еще и внешний цикл, то его не следует делать бесконечным. Я не знаю какае у тебя критерии для перестановки, но не исключаю, что в какой-то ситуации выхода из внешнего цикла не будет.
Навигация
Перейти к полной версии