"Комплексные" сплайны

Автор Тема: "Комплексные" сплайны  (Прочитано 10719 раз)

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

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
"Комплексные" сплайны
« : 31-08-2017, 16:33:17 »
В своей повседневной многотрудной работе со сплайнами мне часто попадаются так называемые "комплексные" сплайны - это объекты идентифицируемые как AcDbSpline, но с интересной особенностью: подрыв такого сплайна приводит к разложению последнего на ряд саб-сплайнов - в точности повторяющих контур исходного.
В связи с этим возникают вопросы:
1. Как распознавать такие сплайны без использования подрыва?
2. Как самостоятельно создавать такие сплайны?
Может кто в теме данной ситуации?

Пример комплексного сплайна прилагаю во вложении.
« Последнее редактирование: 31-08-2017, 19:29:47 от Debalance »

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: "Комплексные" сплайны
« Ответ #1 : 01-09-2017, 00:09:06 »
подрыв
Это что такое?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Онлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Re: "Комплексные" сплайны
« Ответ #2 : 01-09-2017, 09:10:45 »
Я полагаю, аналог _.explode :)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #3 : 01-09-2017, 10:20:19 »
Я полагаю, аналог _.explode :)
Вот-вот... Я бы даже выбросил слово "аналог".

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: "Комплексные" сплайны
« Ответ #4 : 01-09-2017, 13:00:29 »
Книга NURBS. Глава 5 - там даже есть алгоритм DecomposeCurve
Насколько я помню, это определяется степенью кривой. Сплайн это Nurbs-кривая и если у неё высокая степень, то её можно разделить на несколько сегментов - кривых Безье меньшей степени

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #5 : 01-09-2017, 13:38:28 »
Книга NURBS. Глава 5 - там даже есть алгоритм DecomposeCurve
Спасибо, дружище trir, за наводку, но мне не очень бы хотелось писать свои кастомные методы, а есть желание использовать уже готовые решения в рамках ObjectARX SDK. Тем более сам AutoCAD прекрасно определяет "высокую степень" конкретного сплайна и в состоянии запустить "алгоритм DecomposeCurve". Поэтому моя первоочередная задача добраться до этих готовых решений зашитых в лоне AutoCAD.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: "Комплексные" сплайны
« Ответ #6 : 01-09-2017, 13:46:57 »
Ну из того, что я обнаружил:
1. Не совпадает количество управляющих точек (controlPoints) и количество узлов (knots). Видно при помощи ARXDBG
2. Совпадают некоторые управляющие точки:

3. Отрицательная площадь:




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

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: "Комплексные" сплайны
« Ответ #7 : 01-09-2017, 14:34:48 »
Цитировать
Совпадают некоторые управляющие точки
так всегда на прямых участках

Цитировать
Не совпадает количество управляющих точек (controlPoints) и количество узлов (knots).
так всегда
knots = controlPoints + degree + 1

Цитировать
Св.4.13  NURBS  кривая  без  внутренних  узлов  является  рациональной  кривой  Безье, поскольку  N_(i,p) (u)  сводятся  к  B_(i,n) (u); сравните  формулы  (4.2)  и  (4.3)  с  уравнением  (1.15). Из  этого, вместе  со  Св.4.7, следует, что  кривые  NURBS  содержат  нерациональные  B-сплайны  и  рациональные  и  нерациональные  кривые  Безье  в  качестве  частных  случаев;

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #8 : 01-09-2017, 15:01:51 »
так всегда
knots = controlPoints + degree + 1

Это не всегда так. Вот выдержка из Википедии:
Цитировать
A common misconception is that each knot is paired with a control point. This is true only for degree 1 NURBS (polylines). In general, the knots break the domain up into knot spans, but each control point corresponds to one basis function which spans a range of (degree+1) knot spans.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: "Комплексные" сплайны
« Ответ #9 : 01-09-2017, 15:02:31 »
Цитировать

    Не совпадает количество управляющих точек (controlPoints) и количество узлов (knots).

так всегда
knots = controlPoints + degree + 1
Судя по всему не всегда. Во всяком случае я средствами AutoCAD нарисовал сплайн с degree - 3, controlPoints - 10 и knots - 11.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: "Комплексные" сплайны
« Ответ #10 : 01-09-2017, 15:07:08 »
по этому и нужно учить теорию - когда её знаешь, этих вопросов просто не возникает
а я уже почти всё забыл... :=(

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #11 : 01-09-2017, 20:56:13 »
Во всей этой математической кутерьме связанной с кнотами и контрол-поинтами меня интересует практическая сторона вопроса, непосредственно касающаяся опубликованного мной чертежа. Речь идёт о создании региона (AcDbRegion). Я провёл небольшой тест:

1. Попытался создать регион из исходного сплайна (команда _REGION). В результате получается вполне себе корректный объект - даже площадь имеет адекватное значение.

2. В тулбаре AutoCAD я нажал вот на эту иконку:

и применив к сплайну команду _EXPLODE я расчленил его на группу примитивов. Если далее к полученной группе попытаться применить команду _REGION, то в текстовом окне мы обнаружим следующий лог:
1 loop extracted.
1 loop rejected.
    Unable to cover wire                   : 1 loop.
0 Regions created.
То же фиаско нас ожидает при использовании команды _BOUNDARY, если в качестве Object type указать Region.

Таким образом наблюдается некоторый дуализм в поведении AutoCAD'а. Что это баг?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: "Комплексные" сплайны
« Ответ #12 : 01-09-2017, 21:03:57 »
Что это баг?
Воспринимай это как ограничение в AutoCAD. Не вижу смысла даже передавать это в ADN DevHelp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #13 : 01-09-2017, 21:18:33 »
Воспринимай это как ограничение в AutoCAD.
Что-то уж больно много ограничений набирается у меня при работе со сплайнами.

Не вижу смысла ...
Я тоже его не вижу. Просто пытаюсь самостоятельно разрулить программную реализацию создания региона для конкретной задачи. Но похоже выше головы не прыгнешь в рамках исходного SDK.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: "Комплексные" сплайны
« Ответ #14 : 01-09-2017, 21:31:39 »
Но похоже выше головы не прыгнешь в рамках исходного SDK.
Думаю, что единственный правильный способ - аппроксимация сплайна с заданной точностью, а затем уже создание региона. Тем более, что точности Region и 3DSolid порядка 1e-6
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #15 : 01-09-2017, 21:46:27 »
Думаю, что единственный правильный способ - аппроксимация сплайна с заданной точностью
Вы намекаете на полилинию с миллиардом вершин? Представляете как раздуется чертёж в котором куча сплайнов?

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

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

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #17 : 01-09-2017, 22:27:51 »
А зачем добавлять его в чертеж?
Нет, я не добавляю его в чертёж. Я просто сравниваю "вес" гипотетического региона созданного из полилинии с большим количеством вершин с "весом" региона на основе исходного сплайна. Последний (в моём понимании) существенно "легче".

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: "Комплексные" сплайны
« Ответ #18 : 02-09-2017, 09:35:05 »
Скорей всего сплайны разбегаются при усечении координат конечных точек в соответствии с текущей точность чертежа...

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #19 : 02-09-2017, 17:28:20 »
Скорей всего сплайны разбегаются при усечении координат конечных точек в соответствии с текущей точность чертежа...
Не понял. Поясните, что Вы имеете ввиду?

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Re: "Комплексные" сплайны
« Ответ #20 : 04-09-2017, 06:57:54 »
да нет, фигню сказал  :(

Оффлайн Николай Горлов

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: "Комплексные" сплайны
« Ответ #21 : 04-09-2017, 11:01:52 »
Во всей этой математической кутерьме связанной с кнотами и контрол-поинтами меня интересует практическая сторона вопроса, непосредственно касающаяся опубликованного мной чертежа. Речь идёт о создании региона (AcDbRegion). Я провёл небольшой тест:

1. Попытался создать регион из исходного сплайна (команда _REGION). В результате получается вполне себе корректный объект - даже площадь имеет адекватное значение.
2. В тулбаре AutoCAD я нажал вот на эту иконку:

и применив к сплайну команду _EXPLODE я расчленил его на группу примитивов. Если далее к полученной группе попытаться применить команду _REGION, то в текстовом окне мы обнаружим следующий лог:
Код: [Выделить]
1 loop extracted.
1 loop rejected.
    Unable to cover wire                   : 1 loop.
0 Regions created.
То же фиаско нас ожидает при использовании команды _BOUNDARY, если в качестве Object type указать Region.
Таким образом наблюдается некоторый дуализм в поведении AutoCAD'а. Что это баг?

команды "_REGION" и "_BOUNDARY" требуют одновременной видимости всех объектов, которые включены в набор. проверил создание области у себя. всё прекрасно создается, если все используемые объекты видны на экране ("_REGION" и "_BOUNDARY" и для целого сплайна и для его кусков). потом зумом оставил правую часть объекта на экране и при выделении - перемещался по чертежу так, что правый  "хвост" скрылся за пределами экрана, а левый появился. всё выделил. нажал Enter - результат: 0 областей.
по поводу того, как создавать такие сплайны - есть команда "_JOIN". Не уверен, но для программной реализации можно поковырять класс AcDbJoinEntityPE

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #22 : 04-09-2017, 11:22:10 »
команды "_REGION" и "_BOUNDARY" требуют одновременной видимости всех объектов, которые включены в набор.
Данная теза вызывает сомнения касательно команды _REGION. Я так понимаю там тупо используется AcDbRegion::createFromCurves для объектов из "селекшн-сета" и если объект выбран - то он ВЫБРАН, причём здесь видимость? На каком Автокаде Вы производили тест?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: "Комплексные" сплайны
« Ответ #23 : 04-09-2017, 11:29:01 »
команды "_REGION" и "_BOUNDARY" требуют одновременной видимости всех объектов, которые включены в набор.
Это условие требуется только для _BOUNDARY.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Николай Горлов

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: "Комплексные" сплайны
« Ответ #24 : 04-09-2017, 11:41:50 »
Данная теза вызывает сомнения касательно команды _REGION. Я так понимаю там тупо используется AcDbRegion::createFromCurves для объектов из "селекшн-сета" и если объект выбран - то он ВЫБРАН, причём здесь видимость? На каком Автокаде Вы производили тест?
упс... да, видимость только для _BOUNDARY. _REGION отрабатывает нормально, даже если объект(ы) полностью за пределами чертежа
проверял в 2014x64 и 2017x64

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #25 : 04-09-2017, 11:49:11 »
_REGION отрабатывает нормально
Ещё раз, чтобы я понял, Вы делаете следующее:
1. Взорвали исходный контур.
2. Применили команду _REGION к группе полученных сплайнов.
3. Наблюдаете полученный регион.

Ну если это так, то я отказываюсь понимать моё поведение Автокада!

Оффлайн Николай Горлов

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: "Комплексные" сплайны
« Ответ #26 : 04-09-2017, 12:10:16 »
та могу даже видео снять ))). варианты тестов с _REGION:
1. к исходному сплайну применяю _REGION (создается область с одной ручкой перемещения)

2. переоткрываю чертеж.
a)_EXPLODE для сплайна.
б)_REGION. Выбираю рамкой все 12 кусков. создается область с 12 ручками перемещения

3. переоткрываю чертеж.
а)_EXPLODE для сплайна.
б)_JOIN для кусков сплайна.
в)_REGION. создается область с 12 ручками перемещения

PS: напрягает во всём этом только то, что для указанного сплайна неверно определяется площадь (окно свойств, arxdbg, сервис->сведения->площадь). но кажись я нашел, какая команда автокада привносит эту изюминку :). Нарисовал два куска сплайна друг под другом. Есть такая команда - "соединение кривых". Воспользовался ей. Она дорисовала два куска сплайна самостоятельно, чтоб  было красивенько :) и замкнуто. Потом объединил сплайны в кучу. В результате - площадь "-1".

Ну если это так, то я отказываюсь понимать моё поведение Автокада!
:) пора переустанавливать кажись.

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #27 : 04-09-2017, 13:10:55 »
пора переустанавливать кажись.
Полагаю дело не в этом. Протестировал на двух машинах (Acad 2016x64), результат тот же - регион не создаётся. Программная реализация показывает, что метод AcDbRegion::createFromCurves возвращает Acad::eInvalidInput.

Подтверждаю, что использование _JOIN решает проблему - создаётся регион, но всего лишь с одной ручкой (вместо 12-ти как у Вас) . Вот скриншот:

Оффлайн Николай Горлов

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: "Комплексные" сплайны
« Ответ #28 : 04-09-2017, 15:02:24 »
хм... вот не зря я не люблю сплайны, и везде, где только можно, стараюсь переводить их в полилинии. ради интереса поковырялся во всех установленных автокадах. задача была просто получить из исходного замкнутого сплайна (без лишних телодвижений, только команда _REGION) область и посмотреть её площадь. Вот такая занимательная математика выходит, и сразу видно, когда кто-то ковырялся руками в исходном коде автокада :) (кстати, автокады 2012-2014 область создают, но в логе командной строки есть сообщение об ошибке)
акад2010:   87.6068
акад2011:   87.6068
акад2012:   87.6024      Ошибка операции моделирования: Замкнутое ребро в многореберном каркасе.
акад2013:   87.6022      Ошибка операции моделирования: Замкнутое ребро в многореберном каркасе.
акад2014:   87.6022      Ошибка операции моделирования: Замкнутое ребро в многореберном каркасе.
акад2015:   87.5999
акад2016:   87.5999
акад2017:   87.6024

Дальше просто ради смеха решил в 2016-м автокаде пересобрать сплайн (_EXPLODE + _JOIN), а затем сделать на его основе область. Всё получилось, только площадь стала 87.6018, хоть была 87.5999. Оно то в принципе и не критично, погрешность приблизительно 0.002%.
Затем я превратил сплайн в полилинию (получилось 646 точек). Ну и пробежал создание области уже для аппроксимированного сплайна (для полилинии, короче говоря). Так вот. Результат во всех автокадах одинаковый (в принципе как и площадь самой полилинии) 87.5352

PS: Дальше идет сугубо личное мнение. Если программа пишется за денежку, то покупатель должен получать одно и то же число в ЛЮБОМ автокаде (проблемы самого автокада покупателя как-то не сильно утешают. например, площадь здания не усыхается/разрастается сама по себе в зависимости от того, в каком автокаде печатается сопроводительная документация). Второе, исходный материал может быть в любом допустимом виде, но привести его к какому-то одному промежуточному, с которым удобно работать, намного проще, чем обрабатывать рандомный ввод пользователя. Ну и третье из собственного опыта, есть чертеж карьера, нарисованный 3D сплайнами. Еле шевелится этот чертеж на 3D орбите на стареньком компике. Перегнали в 3D полилинии без видимого ухудшения качества (вроде и точек мульйон стал :), а чертеж начал плавно вращаться).
PS2: Так что Наумович, как всегда прав :), без аппроксимации дела не будет, тем более, что как я понял, её и сохранять то в чертеже не нужно

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Re: "Комплексные" сплайны
« Ответ #29 : 04-09-2017, 16:25:50 »
Площадь фигуры ограниченная сплайном(ми) не может быть вычислена по формуле (т.е. с точностью до машинного эпсилон). Вероятнее всего в алгоритме подсчёта площади используется (опять же таки) предварительная аппроксимация. Именно от различного шага аппроксимации (используемого в разных версиях AutoCAD) и получаются разные величины площади. Где-то уже обсуждалось, что значение AcGeContext ::gTol менялось от версии к версии - возможно это и есть ответ на вопрос.

... вроде и точек мульйон стал , а чертеж начал плавно вращаться ...
А это как сравнение векторной и растровой графики: векторная и чётче и ярче и меньше по объёму, но зато затратнее по машинному времени.

Так что Наумович, как всегда прав
Возможно и прав. Но это своего рода решение-заглушка позволяющее экстенсивным способом разрулить актуальные трудности. Я надеюсь, что Autodesk через годы совершенствования своего Детища всё-таки отшлифует тематику сплайнов.  :D