| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Преобразование широкой полилинии в конур и обратно

Преобразование широкой полилинии в конур и обратно

Ответ
Поиск в этой теме
Непрочитано 02.05.2017, 22:25 #1
Преобразование широкой полилинии в конур и обратно
AY
 
webcad.pro
 
Московская обл.
Регистрация: 06.01.2005
Сообщений: 501

Коллеги, не подскажет ли кто-нибудь готового решения которое позволяло бы преобразовать полилинию с явно заданной шириной (global width) в ее контурное представление в виде одной замкнутой полилинии? И уж совсем хорошо было бы иметь обратное решение.

Миниатюры
Нажмите на изображение для увеличения
Название: x.png
Просмотров: 46
Размер:	872 байт
ID:	187368  

Просмотров: 12169
 
Непрочитано 03.05.2017, 00:23
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,831


fillmode поменяй ))
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 03.05.2017, 01:19
3 | 1 #3
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


"Туда" может программа Lee Mac, а вот "обратно" - под вопросом. Если полилиния "равноширокая" по всей длине, то можно взять среднюю линию (например, подобием, или еще были на форуме решения, вроде) и присвоить ей нужную глобальную ширину.
skkkk вне форума  
 
Непрочитано 03.05.2017, 06:57
#4
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Заменить на мультилинию и обратно.
Boxa вне форума  
 
Непрочитано 03.05.2017, 09:21
#5
kp+

идущий по граблям
 
Регистрация: 26.05.2005
Сообщений: 5,093


Цитата:
Сообщение от skkkk Посмотреть сообщение
Если полилиния "равноширокая" по всей длине, то можно взять среднюю линию (например, подобием, или еще были на форуме решения, вроде)
Например, MPL из PLTOOLS. В принципе, справляется и с полилиниями, имеющими разную ширину сегментов, но если не переусердствовать. С полилиниями, которые "поперерек себя шире" работает не совсем адекватно
kp+ вне форума  
 
Автор темы   Непрочитано 03.05.2017, 16:56
#6
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


Кулик Алексей aka kpblc, fillmode - знаю, но это слишком радикально :)

skkkk, вот это похоже то, что надо, но есть существенный недостаток - не работает при наличии дуговых сегментов, а это мне бы хотелось иметь. Я бы променял переменную толщину на сегменты :)

Boxa, замена на мультилинию идея интересная, но мне на первый взгляд не подходит. Да и не развивают мультилинию в Автокаде - хотя потенциал у нее мог бы быть неплохой. Я даже удивляюсь почему - как начал работать с версией 2000 так до сих пор никакого движения.

Всем, коллеги спасибо на наводки, особенно за Lee Mac. Припоминаю, что некогда Евгений Елпанов упоминал, что делал программый офсет для полилиний - в сущности это большая половина дела...
AY вне форума  
 
Непрочитано 03.05.2017, 19:55
#7
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от kp+ Посмотреть сообщение
"поперерек себя шире" работает не совсем адекватно
Все дело в математике. Этот вопрос обсуждался здесь Как построить среднюю линию между непараллельными?
Наилучший результат дает метод "катящегося камня", правда для "хитрой" геометрии нужно повозится с настройками и по времени может быть достаточно долго

__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 03.05.2017, 23:19
#8
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


А может попробовать свое альтернативное решение на базе двухстороннего офсета?

В таком случае второй вопрос к знатокам: где искать "лучший" двухсторонний офсет?
AY вне форума  
 
Непрочитано 04.05.2017, 17:57
#9
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


AY,
Один из них приведен в статье в качестве примера https://dwg.ru/pub/9 источник здесь
Offset LISP Routine just needs small update. Thanks!
Offset Polyline Section

Dynamic Offset

Multiple Offset Lisp
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 04.05.2017, 22:07
#10
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


VVA, Владимир, большое спасибо - такое обилие вариантов - как-то даже теряешься...
В общем попробую о результатах доложу.

----- добавлено через ~12 мин. -----
VVA, у вас в примере https://dwg.ru/pub/9, если я правильно понимаю, лишняя скобка в конце.

----- добавлено через ~3 ч. -----
В первом приближении получилось нижеследующее безобразие.
Для начала стремился обыграть свои нужды, поэтому не делал обработку замкнутых и самопересеченных полилиний. Толщина отступа берется из "глобальной толщины".

Код:
[Выделить все]
 (defun C:test (/ d obj1 ent1 adoc *error* undo lays Flag obj2 obj3)

  (defun *error* (msg)(vla-EndUndoMark adoc))
  
  (vl-load-com)
  (setq 
    adoc (vla-get-activedocument (vlax-get-acad-object))
    lays (vla-get-layers adoc))
    
  (vla-StartUndoMark adoc)
  (setvar "CMDECHO" 0)
  
  ;(if (null *OFF2*)
  ;  (setq *OFF2* (abs (getvar "OFFSETDIST"))))
  
  ;(if (zerop *OFF2*)
  ;  (setq *OFF2* 1))
  
  (setq d (getvar "UNDOCTL"))
  
  (cond 
    ((= d 0) (vl-cmdf "_.UNDO" "_All"))
    ((= d 3) (vl-cmdf "_.UNDO" "_Control" "_All"))
    (t nil))
    
  ;(princ "\n Величина смещения <")
  ;(princ *OFF2*)
  ;(princ ">: ")
  
  ;(initget 6)
  ;(if (null (setq d (getdist))) 
  ;  (setq d *OFF2*))
    
  (setq  
    ;*OFF2* d    
    undo    0 
    Flag    t)
    
  (initget "Undo Отмени Г J Exit Выход У D _Undo Undo Undo Undo Exit Exit Exit Exit")
  
  (while Flag
    (setq 
      ent1 
      (entsel (strcat "\n Выберите объект [" (if (not (zerop undo)) "Отмени/" "") "Выход] <выход>: ")))
      
    (cond 
      ((= ent1 "Undo")
        (if (not (zerop undo))
          (progn
            (vl-cmdf "_UNDO" "_B")
            (setq undo (1- undo)))
          (alert "Нечего больше отменять")))
          
      ((= ent1 "Exit")
        (setq Flag nil))
      
      ((null ent1)
        (if (= (getvar "ERRNO") 52)
        (setq Flag nil)
        (princ " *** Мимо ***")))
      
      (t 
        (setq obj1 (vlax-ename->vla-object (car ent1)))
        (cond 
          ((= (vla-get-lock (vla-item lays (vla-get-layer obj1))) :vlax-true)
            (alert "На блокированном слое!"))
          ((vlax-method-applicable-p obj1 'Offset)
            (vl-cmdf "_UNDO" "_M")
            (setq undo (1+ undo))
            
            ;; Отступ шириной в половину толщины полилинии
            (setq d (* 0.5 (cdr (assoc 43 (entget (car ent1))))))
            (if (<= d 0) (setq d 100))
            
            (setq obj2 (vla-offset obj1 d))
            
            (setq obj2 (car (vlax-safearray->list (vlax-variant-value obj2))))
            ;(vla-put-color obj2 1)
            
            (setq obj3 (vla-offset obj1 (- 0 d)))
            
            (setq obj3 (car (vlax-safearray->list (vlax-variant-value obj3))))
            ;(vla-put-color obj3 3)

            (poly-union obj2 obj3)
            
            (vla-delete obj1)
            (vla-delete obj2)
            (vla-delete obj3)
            
            )
          (t (alert "Не удается создать объект, подобный данному")))))
            
    (initget "Undo Отмени Г J Exit Выход У D _Undo Undo Undo Undo Exit Exit Exit Exit"))
  (vla-EndUndoMark adoc)
  (princ))
  
  
(defun poly-union (obj2 obj3 / ent2 ent3 pt-number ent2-210 new-pl)
  (setq 
    ent2 (entget (vlax-vla-object->ename obj2))
    ent3 (entget (vlax-vla-object->ename obj3)))
    
  ;; Количество вершин контурной полилинии
  (setq 
    pt-number
    (+
      (length
        (vl-remove-if-not 
          '(lambda (x) (= (car x) 10)) ent2))
      (length
        (vl-remove-if-not 
          '(lambda (x) (= (car x) 10)) ent3))))

  (setq 
    ent3 
    (vl-remove-if-not 
      '(lambda (x) (member (car x) '(10 40 41 42) )) 
      ent3))
    
  (setq 
    ent3
    (mapcar 
      '(lambda (x) 
        (cond
          ((= (car x) 42) (cons 42 (- (cdr x))))
          (t x)))
      ent3))

  (setq ent3 (reverse ent3))
    
  ;(princ "\n\n\n")  
  ;(print ent3)
  ;(princ "\n\n\n") 

  (setq ent3 (cons (cons 42 0) (cdr ent3)))
  
  (setq ent2-210 (assoc 210 ent2))

  (setq 
    ent2 
    (vl-remove-if 
      '(lambda (x) (member (car x) '(-1 210 330 5)))
      ent2))
  
  (setq new-pl (append ent2 ent3 (list ent2-210)))
  
  (setq 
    new-pl 
    (mapcar 
      '(lambda (x) 
        (cond
          ((= (car x) 90) (cons 90 pt-number))
          ((= (car x) 70) (cons 70 1))
          ((= (car x) 40) (cons 40 0))
          ((= (car x) 41) (cons 41 0))
          ;((= (car x) 42) (cons 42 0))
          ((= (car x) 43) (cons 43 0))
          (t x)))
      new-pl))
  
  ;(princ new-pl)
  ;(print (entmake new-pl))
  (entmake new-pl))  

Последний раз редактировалось AY, 05.05.2017 в 23:11.
AY вне форума  
 
Непрочитано 05.05.2017, 11:51
#11
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от skkkk Посмотреть сообщение
"Туда" может программа Lee Mac'а,
Цитата:
Сообщение от AY Посмотреть сообщение
вот это похоже то, что надо, но есть существенный недостаток - не работает при наличии дуговых сегментов, а это мне бы хотелось иметь.
Пробуй там же Advanced Polyline Outline
Описание
Цитата:
This program allows the user to construct the outline silhouette of an LWPolyline with straight and/or arc segments with varying or constant width;
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 05.05.2017, 15:41
#12
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


VVA, хотел вчера про нее написать - не успел. Однако, как я понял, она корректно отрабатывает лишь на таком дуговом сегменте, угол касательной в начале которого совпадает с углом соседнего прямого сегмента или с углом касательной дугового в этой точке. Если чертить полилинию с опцией "Дуга", то там так и происходит. На деле же полилиния "собирается" из кусков: прямых, дуговых - и далеко не факт, что это условие выполнится. На глазок кажется, что ровно, но на деле мне вручную такой точности так и не удалось добиться - все одно: если собираю полилинию из кусков, то результат плохой. Результирующий контур не получается целым - дуговые сегменты отдельно от прямых, и концы их не совпадают. То есть, для получения цельного контура придется потанцевать. Поэтому, придется либо как-то предварительно программно модифицировать дуговые сегменты, так, чтобы угол касательной в начале дугового сегмента совпадал с углом соседнего сегмента в точке их пересечения (пока даже представить не могу, как это должно работать), либо искать другие пути решения.

Сам недавно озадачился вопросом программного создания охранных зон вокруг подземных коммуникаций (см. первую миниатюру).
Подошел к вопросу с одной стороны: создавал полилинии подобием в обе стороны на нужном расстоянии, потом удлинял их на крайних сегментах на величину полуширины зоны (у нас по соглашению с проектировщиками крайние сегменты - всегда прямые) , дорисовывал замыкающие сегменты и объединял. Выяснилось, что программа дает сбой в случаях, когда крайний сегмент исходной полилинии повернут относительно предыдущего сегмента (оба прямые), например, на 90 градусов и длина этого сегмента меньше полуширины зоны (расстояния смещения). При таком раскладе количество вершин одной из подобных линий на одну меньше, чем у исходной, и угол удлинения конечного сегмента будет уже другой (ситуация изображена на второй миниатюре). Тут в вычислениях можно просто голову поломать.
Буквально на днях в голову пришел еще один вариант - с использованием "опустошения внутренностей" широкой полилинии (примерно из оперы темы топика). Делаю копию полилинии, удлиняю крайние сегменты на полуширину охранной зоны, и назначаю ширину по ширине охранной зоны. Затем полилинию "выполняю" (от слова полый) и все готово. Но тут вот столкнулся с двумя проблемами. Во первых, иногда зоны бывают несимметричными: с одной стороны от трубы 2 метра, а с другой - 3. Ладно, это, допустим, решаемо: делаем подобие на 1 в одну сторону (и этой линии назначаем ширину 2) и на 1.5 в другую (ей - ширину 3). Затем программой Lee MacOutline Objects строим "опоясывающую" полилинию и получаем искомый контур. Вроде бы все хорошо, но кровь портит это ограничение на "угол атаки" дугового сегмента. Кто знает, как бы это побороть? Или может, кто еще имеет идеи, как сделать охранную зону, в частном случае - несимметричную?

Еще рассматриваю вариант перед применением Polyline Outline сделать апрроксимацию дуговых сегментов (PL-NoArc), но есть большие подозрения, что на длинных полилиниях с большим количеством дуговых сегментов при достаточной точности обработка будет долгой. Порой при простом выборе такой полилинии происходит серьезное такое подвисание - хоть ручки отключай.

----- добавлено через ~1 ч. -----
AY, только сейчас увидел код. Проверил - вроде решает обозначенную мной проблему. Попробую посерьезней - отпишусь если что. Спасибо.
Миниатюры
Нажмите на изображение для увеличения
Название: Зона 2х3.PNG
Просмотров: 91
Размер:	4.0 Кб
ID:	187550  Нажмите на изображение для увеличения
Название: Ошибка обработки.PNG
Просмотров: 75
Размер:	4.0 Кб
ID:	187551  
skkkk вне форума  
 
Непрочитано 05.05.2017, 18:22
#13
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от skkkk Посмотреть сообщение
то на длинных полилиниях с большим количеством дуговых сегментов при достаточной точности обработка будет долгой.
Все зависит от того какова требуемая точность. В свое время, при тестировании мы этот вопрос с KAI ( светлая ему память) обсуждали. Мне видится, что при аппроксимировании дуговых сегментов полилиний нужно воспользоваться предельным отклонением хорды (опция S)
Миниатюры
Нажмите на изображение для увеличения
Название: PLNoArc.png
Просмотров: 83
Размер:	73.9 Кб
ID:	187557  
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 05.05.2017 в 22:08.
VVA вне форума  
 
Автор темы   Непрочитано 05.05.2017, 19:39
#14
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


Цитата:
Сообщение от VVA Посмотреть сообщение
Пробуй там же Advanced Polyline Outline
В первый момент вроде бы все хорошо, но потом вылазят недостатки на которые указал skkk - см. вложение.
Миниатюры
Нажмите на изображение для увеличения
Название: Снимок.PNG
Просмотров: 108
Размер:	14.6 Кб
ID:	187559  
AY вне форума  
 
Непрочитано 05.05.2017, 20:01
#15
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


AY, всё верно.
Насадил poly-union в свой код по отрисовке зон - полёт нормальный. Погонял со всех сторон, разные варианты, что пришли в голову - багов не обнаружил. Возможно - пока - практика покажет.
Еще раз спасибо, AY - одной головной болью меньше.
Показать бы этот код Ли - может, поучился бы чему
skkkk вне форума  
 
Непрочитано 05.05.2017, 22:05
#16
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от AY Посмотреть сообщение
В первый момент вроде бы все хорошо, но потом вылазят недостатки на которые указал skkk
На сайте чуть ниже есть ограничения
Цитата:
The program will produce best results for LWPolyline arc segments whose vertex locations have not been independently modified following creation of the original LWPolyline; i.e. arc segments which remain tangent to surrounding segments. For arc segments which do not meet the neighbouring segments tangentially, there may be some overlap of objects constituting the resulting outline.
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 05.05.2017, 23:09
#17
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


Цитата:
Сообщение от VVA Посмотреть сообщение
На сайте чуть ниже есть ограничения
Разумеется к английскому гражданину Ли-Маку никаких претензий, только благодарности - умница и молодец.

Цитата:
Сообщение от skkkk Посмотреть сообщение
Показать бы этот код Ли - может, поучился бы чему
Не надо впадать в преувеличения :)
Гражданин решал свои задачи - полилинии переменной ширины, мы же решили свои полилинии одинаковой ширины - только и всего. Не нам учить такого мастера :)
AY вне форума  
 
Непрочитано 06.05.2017, 07:35
#18
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от AY Посмотреть сообщение
Разумеется к английскому гражданину Ли-Маку никаких претензий, только благодарности - умница и молодец.
Согласен на 200%, это я к тому, что сам описанные ограничения заметил только вчера
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 09.05.2017, 13:06
1 | #19
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от AY Посмотреть сообщение
Разумеется к английскому гражданину Ли-Маку никаких претензий, только благодарности - умница и молодец.
Я написал письмо Lee и получил ответ. Проверить сейчас нет возможности, поэтому привожу текст письма полностью
Цитата:
Hi Vladimir,
Thank you for your email, I very much appreciate your gratitude for my site and I'm flattered that my site & programs are being discussed on a Russian forum!

I have previously used the method of offsetting the polyline by half of the constant width to either side and then joining the end points of the resulting polylines, as demonstrated by the attached program ConstantWidthPolylineOutlineV1-0.lsp dated February 2015) which I may have shared on a forum at some point, but have yet to publish to my site.

However, looking over the code for this program, I would now be inclined to write the program in the following way:

Код:
[Выделить все]
(defun cwpolyout ( obj / cat enx pl1 pl2 vt1 vt2 )
    (setq cat (lambda ( f a / r ) (if (not (vl-catch-all-error-p (setq r (vl-catch-all-apply f a)))) r)))
    (cond
        (   (or (not (setq pl1 (car (cat 'vlax-invoke (list obj 'offset (/ (vla-get-constantwidth obj)  2.0))))))

                (not (setq pl2 (car (cat 'vlax-invoke (list obj 'offset (/ (vla-get-constantwidth obj) -2.0))))))
            )
        )
        (   (vlax-curve-isclosed obj))
        (   (progn
                (setq enx (entget (vlax-vla-object->ename pl1))
                      vt1 (vl-remove-if-not '(lambda ( x ) (or (= 10 (car x)) (= 42 (car x)))) enx)
                      vt2 (vl-remove-if-not '(lambda ( x ) (or (= 10 (car x)) (= 42 (car x)))) (entget (vlax-vla-object->ename pl2)))
                )
                (entmod
                    (append
                        (subst '(43 . 0.0) (assoc 43 enx)
                            (subst (cons 70 (logior 1 (cdr (assoc 70 enx)))) (assoc 70 enx)
                                (subst (cons 90 (/ (+ (length vt1) (length vt2)) 2)) (assoc 90 enx) (reverse (member (assoc 38 enx) (reverse enx))))
                            )
                        )
                        (reverse (cons '(42 . 0.0) (cdr (reverse vt1))))
                        (append (cdr (reverse (mapcar '(lambda ( x ) (if (= 42 (car x)) (cons 42 (- (cdr x))) x)) vt2))) '((42 . 0.0)))
                        (list (assoc 210 enx))
                    )
                )
            )
            (vla-delete pl2)
            pl1
        )
    )
)
Perhaps I'll publish one of these programs to my site at some point.

However, unfortunately this method of generating the polyline outline is not compatible with the method implemented by my Advanced Polyline Outline program, as the offset cannot be performed with segments of variable width and it is ambiguous how the outline should be represented where certain segments meet (even AutoCAD glitches for some vertices!).

Kind Regards,

Lee
Вложения
Тип файла: lsp ConstantWidthPolylineOutlineV1-0.lsp (5.7 Кб, 44 просмотров)
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 06.06.2017, 22:43
#20
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


Цитата:
Сообщение от VVA Посмотреть сообщение
Я написал письмо Lee и получил ответ. Проверить сейчас нет возможности, поэтому привожу текст письма полностью
Владимир, запоздало благодарю - не часто заглядываю на форум - пропустил ваше сообщение.

Программу Ли Мака попробовал работает как надо. Корректно обрабатывает замкнутые полилинии, но немного не корректно самопересеченные (в том числе замкнутые).
AY вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Преобразование широкой полилинии в конур и обратно

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Контур с штриховкой по полилинии (полилиниям) Rusakov Программирование 14 26.12.2018 21:24
.NET Изобретаем велосипед, или как найти ближайшую вершину полилинии? La Persona .NET 14 05.12.2013 10:56
Преобразование DWG в SVG и обратно для работы в веб приложении. Василий Гнучев Программирование 20 07.06.2012 06:21
Преобразование полилинии KuIZZInI AutoCAD 3 17.05.2011 17:19
Преобразование координат вершин полилинии из мировой системы координат в текущую молодой человек Программирование 1 16.01.2010 22:57