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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > AutoLISP. Как получить координаты двух соседних вершин выбранного фрагмента полилинии?

AutoLISP. Как получить координаты двух соседних вершин выбранного фрагмента полилинии?

Ответ
Поиск в этой теме
Непрочитано 16.04.2015, 14:21 #1
AutoLISP. Как получить координаты двух соседних вершин выбранного фрагмента полилинии?
MrBrown
 
ПенсионЭр
 
Регистрация: 26.06.2009
Сообщений: 361

Здравствуйте!
Указывая отрезок, научился находить координаты начала и конца.
Видел макросы, возвращающие все вершины полилинии.
А как найти координаты только двух соседних вершин, указав курсором какой-нибудь фрагмент на полилинии?
Спасибо.
Просмотров: 5726
 
Непрочитано 16.04.2015, 14:33
#2
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


используй vlax-curve-функции
gomer вне форума  
 
Автор темы   Непрочитано 16.04.2015, 14:37
#3
MrBrown

ПенсионЭр
 
Регистрация: 26.06.2009
Сообщений: 361


gomer, а без них? Только на автолиспе. Я пока его осваиваю.
Или подскажи, пожалуйста, где почитать про эти функции.
Мне, по большому счету, надо всего-ничего: ткнуть курсором во фрагмент полилинии и поставить рядом с ним MTEXT из двух строк: 1-я: угол поворота и 2-я: длина фрагмента.
MrBrown вне форума  
 
Непрочитано 16.04.2015, 15:12
#4
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от MrBrown Посмотреть сообщение
где почитать про эти функции.
в справке почитай
gomer вне форума  
 
Непрочитано 16.04.2015, 18:55
#5
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Пример
Код:
[Выделить все]
 
(vl-load-com)
(setq pl (entsel "\nSelect polyline: "))
(setq point (cadr pl)
      pl (vlax-ename->vla-object(car pl))
      )
;;;В point - точка выбора полилинии
;;;Находим ближайшую точку полилинии
(setq point (vlax-curve-getClosestPointTo pl point))
;;;Узнаем параметр полилинии в точке
;;;Параметр целая часть - номер вершины, начиная с 0
(setq param (vlax-curve-getParamAtPoint pl point))
(setq vx1 (vlax-curve-getPointAtParam pl (fix param))) ;_предыдущая вершина
(setq vx2 (vlax-curve-getPointAtParam pl (1+ (fix param)))) ;_следующая вершина

__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 17.04.2015, 09:01
#6
MrBrown

ПенсионЭр
 
Регистрация: 26.06.2009
Сообщений: 361


VVA, работает! Большое спасибо за код и за комментарии в нём. Продолжу ваять свой макрос
MrBrown вне форума  
 
Непрочитано 17.04.2015, 22:47
#7
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Снабдил комментариями твой макрос
Код:
[Выделить все]
 
(defun C:DATAR ()
  (vl-load-com)
;;;   (setq |CMDECHO| (getvar "cmdecho"))
  (setvar "cmdecho" 0)
  (set osm (getvar "osmode"))
  (setq pl (entsel "\nВыберите фрагмент полилинии/отрезок: "))
  (setq	pt1 (cadr pl)
	pl    (vlax-ename->vla-object (car pl))
  )
  (if (eq (vla-get-ObjectName pl) "AcDbLine")
    ;;Отрезок
    (setq vx1 (vlax-safearray->list
		(vlax-variant-value (vla-get-StartPoint pl))
	      )
	  vx2 (vlax-safearray->list
		(vlax-variant-value (vla-get-EndPoint pl))
	      )
    )
    (progn
;;;В pt1 - точка выбора полилинии
;;;Находим ближайшую точку полилинии
      (setq pt1 (vlax-curve-getClosestPointTo pl pt1))
;;;Узнаем параметр полилинии в точке
;;;Параметр целая часть - номер вершины, начиная с 0
      (setq param (vlax-curve-getParamAtPoint pl pt1))
      (setq vx1 (vlax-curve-getPointAtParam pl (fix param))) ;_предыдущая вершина
      (setq vx2 (vlax-curve-getPointAtParam pl (1+ (fix param)))) ;_следующая вершина
    )
  ) ;_if
  (setq ang (angtos (- (/ pi 2) (angle vx1 vx2)) 1 4))
;_ Последние две цифры - это представление угла и кол-во знаков после запятой.
;_ Представление: 
;_ 0 - градусы
;_ 1 - градусы, минуты, секунды
;_ 2 - грады
;_ 3 - радианы
;_ 4 - геодезическое представление (с указанием сторон света)
  (setq ang (vl-string-subst "%%d" "d" ang))
  (setq len (rtos (distance vx1 vx2) 2 3))
  (setvar "osmode" 512)
  (setq PT1 (getpoint "Укажите точку вставки середины текста: "))
  (setq PT2 (getpoint pt1 "\nУкажите направление текста: "))
;;;Text data
  (setq TAG (strcat ang "\n(" len " м)"))
  (setq ang (angle PT1 PT2))
;;;TEXT TO PRINT ON SCREEN
  (entmake (list
	     (cons 0 "MTEXT")
	     (cons 100 "AcDbEntity")
	     (cons 100 "AcDbMText")
	     (cons 7 "Standart")
	     (cons 8 "Направление-расстояние")
	     (cons 71 5)
	     (cons 72 5)		;выравнивание текста (5 - середина)
	     (cons 73 1)
	     (cons 10 PT1)
;;;(cons 11 (list 1.0 0.0 0.0))
	     (cons 50 ANG)
;;;(cons 41 19.35)
	     (cons 40 (* 0.1 (strlen TAG)))
	     (cons 44 1.0)
	     (cons 1 TAG)
	   )
  )
  (setvar "osmode" osm)
  (setvar "cmdecho" 1)
  (redraw)
  (princ)
)
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 18.04.2015 в 22:58. Причина: заменил point на pt1
VVA вне форума  
 
Автор темы   Непрочитано 18.04.2015, 14:44
#8
MrBrown

ПенсионЭр
 
Регистрация: 26.06.2009
Сообщений: 361


VVA, спасибо за помошь. Сам - ну очень долго искал бы, как заменить "d" на знак градуса.
Теперь о работе программы:
После ввода в ком.строке сразу выдает ошибку:
"; ошибка: неверный тип аргумента: symbolp nil"
После удаления строк, связанных с привязкой (я их закомментировал), программа стала работать, но правильно только с отрезками.
А с полилинией – отстает «на пол-такта»: вставляет значения не указанного фрагмента, а предыдущего (не по начертанию, а по временной хронологии). Например, указываю последовательно 3-й, 9-й, 7-й, 5-й, 16-й фрагменты. Программа выводит на экран значения 3-го, 3-го, 9-го, 7-го, 5-го фрагментов.
MrBrown вне форума  
 
Непрочитано 18.04.2015, 15:28
#9
Кулик Алексей aka kpblc
Moderator

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


Без анализа кода:
Код:
[Выделить все]
 
(defun c:datar (/ ang len osm param pl point pt1 pt2 tag vx1 vx2)
  (vl-load-com)
;;;   (setq |CMDECHO| (getvar "cmdecho"))
  (setvar "cmdecho" 0)
  (set osm (getvar "osmode"))
  (setq pl (entsel "\nВыберите фрагмент полилинии/отрезок: "))
  (setq point (cadr pl)
        pl    (vlax-ename->vla-object (car pl))
        ) ;_ end of setq
  (if (eq (vla-get-objectname pl) "AcDbLine")
    ;;Отрезок
    (setq vx1 (vlax-safearray->list
                (vlax-variant-value (vla-get-startpoint pl))
                ) ;_ end of vlax-safearray->list
          vx2 (vlax-safearray->list
                (vlax-variant-value (vla-get-endpoint pl))
                ) ;_ end of vlax-safearray->list
          ) ;_ end of setq
    (progn
;;;В point - точка выбора полилинии
;;;Находим ближайшую точку полилинии
      (setq pt1 (vlax-curve-getclosestpointto pl pt1))
;;;Узнаем параметр полилинии в точке
;;;Параметр целая часть - номер вершины, начиная с 0
      (setq param (vlax-curve-getparamatpoint pl pt1))
      (setq vx1 (vlax-curve-getpointatparam pl (fix param))) ;_предыдущая вершина
      (setq vx2 (vlax-curve-getpointatparam pl (1+ (fix param)))) ;_следующая вершина
      ) ;_ end of progn
    ) ;_if
  (setq ang (angtos (- (/ pi 2) (angle vx1 vx2)) 1 4))
 ;_ Последние две цифры - это представление угла и кол-во знаков после запятой.
 ;_ Представление: 
 ;_ 0 - градусы
 ;_ 1 - градусы, минуты, секунды
 ;_ 2 - грады
 ;_ 3 - радианы
 ;_ 4 - геодезическое представление (с указанием сторон света)
  (setq ang (vl-string-subst "%%d" "d" ang))
  (setq len (rtos (distance vx1 vx2) 2 3))
  (setvar "osmode" 512)
  (setq pt1 (getpoint "Укажите точку вставки середины текста: "))
  (setq pt2 (getpoint pt1 "\nУкажите направление текста: "))
;;;Text data
  (setq tag (strcat ang "\n(" len " м)"))
  (setq ang (angle pt1 pt2))
;;;TEXT TO PRINT ON SCREEN
  (entmake (list
             (cons 0 "MTEXT")
             (cons 100 "AcDbEntity")
             (cons 100 "AcDbMText")
             (cons 7 "Standart")
             (cons 8 "Направление-расстояние")
             (cons 71 5)
             (cons 72 5) ;выравнивание текста (5 - середина)
             (cons 73 1)
             (cons 10 pt1)
;;;(cons 11 (list 1.0 0.0 0.0))
             (cons 50 ang)
;;;(cons 41 19.35)
             (cons 40 (* 0.1 (strlen tag)))
             (cons 44 1.0)
             (cons 1 tag)
             ) ;_ end of list
           ) ;_ end of entmake
  (setvar "osmode" osm)
  (setvar "cmdecho" 1)
  (redraw)
  (princ)
  ) ;_ end of defun

__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 18.04.2015, 22:45
#10
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


MrBrown,
Цитата:
Сообщение от MrBrown Посмотреть сообщение
А с полилинией – отстает «на пол-такта»:
В моем примере, да и у Алексея так же, есть описка в коде. Переменную point нужно заменить на pt1
Цитата:
(setq pl (entsel "\nВыберите фрагмент полилинии/отрезок: "))
(setq point pt1 (cadr pl)
pl (vlax-ename->vla-object (car pl))
)
----- добавлено через ~2 мин. -----
PS У себя в #7 поправил
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 18.04.2015 в 22:57.
VVA вне форума  
 
Непрочитано 19.04.2015, 07:23
#11
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Обращаю внимание - в этом коде ненадежным участком является entsel. Пока указывается отрезок или "тонкая" полилиния, всё нормально. А если указать на полилинию с "физической" шириной (width), да ещё "широкую", то будет сбой. И не надо думать, что "у меня такого не бывает".

Для универсальности и надежности лучше разбивать задачу на отдельные функции. Например у меня функция ru-get-point-on-ent гарантированно возвращает список (примитив точка) в любых условиях.

Но, если записать всё "в куче" то перед entsel установить
Код:
[Выделить все]
    (setq old_osmode  (getvar "OSMODE")   old_aperture (getvar "APERTURE")) 
    (setvar "OSMODE" 512)
    (setvar "APERTURE" (getvar "PICKBOX"))
А после - еще и
Код:
[Выделить все]
 (setq result (list (car ent_selected) (trans (osnap (trans (cadr ent_selected) 0 1) "_nea") 1 0)))
а также восстановить значения OSMODE и APERTURE.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 20.04.2015, 09:16
#12
MrBrown

ПенсионЭр
 
Регистрация: 26.06.2009
Сообщений: 361


Кулик Алексей aka kpblc, После исправления VVA (#10) и отключения всех трёх строк, связанных с привязкой, работает как надо.
С активацией этих строк (05, 40, 65) выдаёт ошибку:
; ошибка: неверный тип аргумента: symbolp nil
Вопрос: обязательно ли в данной программе включать эти строки? Меня устраивает и так.
ShaggyDoc, спасибо за предупреждение о толщине полилиний.
Большое спасибо всем за помощь!
Вопрос к модераторам: может быть стоит как-то переименовать тему? Мне показалось, что существующее название темы не соответствует содержанию постов.
MrBrown вне форума  
 
Непрочитано 20.04.2015, 09:36
#13
Кулик Алексей aka kpblc
Moderator

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


Охота - переименовывай, кто мешает-то? Тот факт, что тема "свернула" не туда - это отдельная песня.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 04.07.2015, 16:31
#14
Ahntv


 
Регистрация: 16.09.2014
Сообщений: 29


Добрый день dwf-форумчане!
Пробовал загрузить Лисп Datar из 8 поста и 9. Пишет "неверное имя переменной в SETQ: 8" .
Сохраняю как .lsp
Может какие то переменные нужно высавить.
Подскажите пожалуйста?
Ahntv вне форума  
 
Непрочитано 05.07.2015, 13:06
#15
sertor

Геодезист
 
Регистрация: 23.05.2012
Ухта
Сообщений: 1,377


Offtop:
Цитата:
Цитата:
Добрый день dwf-форумчане!

Offtop: А почему dwf а не dwg? Это такая шутка?
__________________
Как-то так.
sertor вне форума  
 
Автор темы   Непрочитано 06.07.2015, 07:55
#16
MrBrown

ПенсионЭр
 
Регистрация: 26.06.2009
Сообщений: 361


Offtop: Клавиша "F" ближе, чем "G". Меньше палец напрягать
MrBrown вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > AutoLISP. Как получить координаты двух соседних вершин выбранного фрагмента полилинии?



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Autolisp: как получить последний ввод (команду, координаты точек)? studentarh LISP 52 04.12.2024 12:15
Помогите вытащить из полилинии все координаты вершин Zaghim Программирование 20 29.08.2021 17:43
Линии электрических соединений Shoorup Программирование 23 07.02.2015 15:13
Как получить координаты вершин линии в полярной системе координат? krusty AutoCAD 6 05.07.2011 10:16
координаты вершин выбранной полилинии на VB? как получить ssv22 Программирование 5 17.07.2008 00:01