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

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

LISP. Отрисовывание полилинии по щелчкам мыши с сохранением координат в список.

Ответ
Поиск в этой теме
Непрочитано 24.07.2013, 22:47 #1
LISP. Отрисовывание полилинии по щелчкам мыши с сохранением координат в список.
Nitrogenium
 
инженер
 
Санкт-Петербург
Регистрация: 02.03.2010
Сообщений: 69

Вот начал писать программку и столкнулся с проблемой. Суть: пользователь вызывает программу, мышкой кликает несколько точек, после чего программа должна выдавать список точек ((x1 y1) (x2 y2)....), а так же отрисовывать полилинию (но без возможности рисовать дуговые элементы). Последнее пока не реализовано в данном коде. Не очень разобрался, как управлять возможностями правой кнопки мыши, Enter и Esc внутри кода, прерывание ввода при нажатии enter. Код:
Код:
[Выделить все]
(defun c:test(/ )
	(setq vertan nil)
	(while (= (getvar "CMDACTIVE") 0); какое условие тут лучше поставить, чтобы при нажатии enter ввод закнчивался?
		(setq t1 (getpoint))
		(setq t2 (list (car t1) (cadr t1)))
		(setq vertan (cons t2 vertan))
	)
	(setq vertan (reverse vertan)); тут должен бы собраться список типа((x1 y1) (x2 y2)...), но только без (nil nil)
)
Не уверен в оптимальности моего кода, но это первое, что пришло в голову. Напишите, если есть идеи.

Последний раз редактировалось Кулик Алексей aka kpblc, 24.07.2013 в 23:43.
Просмотров: 4462
 
Непрочитано 24.07.2013, 23:44
#2
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от Nitrogenium Посмотреть сообщение
; какое условие тут лучше поставить, чтобы при нажатии enter ввод закнчивался?
Посмотри системную переменную ERRNO.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.07.2013, 07:41
#3
gomer

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


Код:
[Выделить все]
 (while (setq t1 (getpoint))
  ; БЛА-БЛА-БЛА
)
gomer вне форума  
 
Непрочитано 25.07.2013, 08:55
#4
Кулик Алексей aka kpblc
Moderator

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


gomer, нажмешь Esc и программа вылетит
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.07.2013, 09:25
#5
VVA

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


Nitrogenium, Велосипед уже изобретен, причем со всякими фенечками
Используй функцию Евгения Елпанова eea-vec. На выходе получишь список точек
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 25.07.2013, 10:06
#6
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,701
Отправить сообщение для Do$ с помощью Skype™


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
gomer, нажмешь Esc и программа вылетит
Код:
[Выделить все]
 (while (setq t1 (getpoint "\nУкажи точку или Enter для завершения, Esc - для вылета программы: "))
  ; БЛА-БЛА-БЛА
)
Предупрежден - вооружен
Do$ вне форума  
 
Непрочитано 25.07.2013, 10:14
#7
Кулик Алексей aka kpblc
Moderator

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


Do$, пользователи не всегда смотрят в ком.строку, я уж не говорю о прочтении и осмыслении написанного там
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.07.2013, 16:59
#8
gomer

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


большинство пользователей несознательно тычут эскейп и сиськами выдавливают контрлбрейк, так что им теперь алерт с лицензионным соглашением показывать каждый раз? к тому же есть же волшебный пендаль в виде *error*
gomer вне форума  
 
Непрочитано 25.07.2013, 22:43
#9
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 811


Цитата:
Сообщение от gomer Посмотреть сообщение
к тому же есть же волшебный пендаль в виде *error*
5+
Олег (jr.) вне форума  
 
Непрочитано 26.07.2013, 07:47
2 | #10
ShaggyDoc

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


Цитата:
к тому же есть же волшебный пендаль в виде *error*
Святая простота....

Очевидно же, что код, который по щелчкам мыши должен сформировать список точек, должен быть функцией, а не "высокоуровневой программой". Его можно использовать многократно. Такая функция должна или вернуть список при штатном завершении или вернуть NIL при отказе. Штатное завершение ввода должно быть штатным для AutoCAD способом - пустой ввод. Отказ - нажатие ESC. Но при этом не должна вылететь основная программа - функция может быть только её маленьким кусочком. Функция *error* срабатывает, когда "поздно пить боржоми" - вся программа уже вылетела, хотя ESC нажата только в каком-то внутреннем кусочке.

Предотвращение вылета всей программы при нажатии ESC (но с разрешением его безопасного использования) надо выполнять с помощью ловушки ошибок. В основе ловушки - функции vl-catch-all-apply, vl-catch-all-error-p и vl-catch-all-error-message. Для их более удобного использования целесообразно написать функцию-аналог конструкции try... except ... end в других языках программирования. Такую функцию (ru-error-catch protected_expression on_error_expression) я уже несколько раз приводил на форуме.

Однако и этого "маловато будет". Чтобы прикладному программисту не мучиться каждый раз, надо сделать и заменитель для функции getpoint - в частном случае, а в общем виде -для всех detxxx. Такая универсальная низкоуровневая функция может иметь описание

(_ru-get-with-default message default_str quoted_get_func initget_param keywords base_point esc_enabled)

В ней предусмотрено всё - текст сообщения, значение по умолчанию, имя штатной функции ввода в "квотированном" виде (например 'getpoint), параметры initget, ключевые слова, базовая точка, допустимость прерывания по ESC.

Функцию _ru-get-with-default для подавляющего большинства случаев применения можно еще обернуть. Например, для ввода точек:
(ru-get-point-reguired message base_point) - запрос точки с обязательным указанием и опциональной базовой точкой
(ru-get-point-or-exit message keywords) - запрос точки с возможностью выхода
и так далее. У меня используется около 10 вариантов ввода точек. А есть еще вводы чисел, ключевых слов и прочего.
Вот теперь можно написать фукцию получения списка точек указанием:

Код:
[Выделить все]
 (defun tst (/ result first_point next_point)
(if (setq first_point (ru-get-point-or-exit "Первая точка для списка" nil))
   (progn
     (setq result (cons first_point result))
     (while (setq next_point (ru-get-point-or-exit-base  "Следующая точка" first_point))
       (setq result      (cons next_point result)  first_point next_point)
     )
   )
)
(reverse result)
)
Это один из многих возможных вариантов. Работает примерно так
Command: (get_list_points)
Первая точка для списка <Выход>:
nil - вышли сразу штатно


Command: (get_list_points)

Первая точка для списка <Выход>:*Cancel*
nil - вышли сразу по ESC, но функция не вылетела, а завершилась

Command: (get_list_points)

Первая точка для списка <Выход>:
Следующая точка <Выход>:
((-11508.8 12019.4 0.0)) - вышли штатно при запросе второй точки, получили только одну

Command: (get_list_points)

Первая точка для списка <Выход>:
Следующая точка <Выход>:
Следующая точка <Выход>:
Следующая точка <Выход>:
Следующая точка <Выход>:
((-11508.8 12019.4 0.0) (-9015.81 13132.5 0.0) (-8732.91 11719.0 0.0) (-10359.6
9687.06 0.0)) - ввели четыре точки


Command: (get_list_points)

Первая точка для списка <Выход>:
nil - прервались сразу штатным пустым вводом и получили NIL

Command: (get_list_points)

Первая точка для списка <Выход>:
Следующая точка <Выход>:
Следующая точка <Выход>:*Cancel*
((-11650.3 13450.6 0.0) (-8450.01 13980.7 0.0))
Прервали по ESC на вводе третьей точки, она не добавилась в список, но вылета программы не произошло.
ShaggyDoc вне форума  
 
Непрочитано 26.07.2013, 10:23
#11
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Offtop: Ух щас пройдусь То ShaggyDoc - с каждой буквой Вашего тескста согласен на 100%, но что у Вас за пример?? Ну Вы же здесь без преувеличения самый опытный в лиспе - но в примере у Вас нет ну не одной строки написаной на нем - что это за "поскалевщина" (setq result (cons next_point result) first_point next_point) и соответствующая обвязка, нету у меня Вашей ru-get-point-or-exit, но пример с ней должен выглядеть как-то так (может чего упустил из-за незнания ее функционала - но по аналогии работы с Вашей)
Код:
[Выделить все]
 (defun tst()
  ((lambda (frec) (frec (ru-get-point-or-exit-base "\nПервая точка " nil)))
    (lambda (pt) (if pt (cons pt (frec (ru-get-point-or-exit-base " Следюущая точка " pt)))))))
Вы распишете все красиво - а кусок кода приведете ну мягко говоря не Вашего уровня, а те для кого Вы написали - и считают это за "чистую монету" - не формируйте неверное представление о лиспе - зачем навешивать три аппендицита в 2 строки - чтоб понятней было?? да в таком ракурсе 20 строк добавить и без коментариев этот код никто за час не разберет. Ну расписали Все верно, что и как для этого использовать, ну если лень Вам - так не пишите код вообще (тем паче без библиотек с Вашими функциями он как-бы не рабочий Offtop: что как-бы и из примера ком. строки видно - писали функцию (tst), а проверяете (get_list_points)), ну а если не лень то напишите как подобает - на Вас же с уважением "ровняются", так и относитесь с ответственностью.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 26.07.2013, 11:00
#12
ShaggyDoc

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


Цитата:
кусок кода приведете ну мягко говоря не Вашего уровня, а те для кого Вы написали
Пишу специально, "по-паскалевски", с переменными, чтобы было понятно. Здесь нет задачи научить писать "по-лисповски" с "лямбдами", чтоб "не дать мужику дохтуром стать". Это задчача для других людей.

Цитата:
без библиотек с Вашими функциями он как-бы не рабочий
Все эти функции не раз здесь публиковал. В них же цепочка вызовов. А здесь была задача показать, как делать "неубиваемый по ESC" код для ввода данных. Насколько помню эти функции были выложены в DwgRuLispLib в виде справочного файла, с правилами для совместной разработки общей библиотеки. Однако идея была угроблена после того, как объявился некий "руководитель фирмы" с идеями "А место для рекламы ведь можно и продать.." и "только при условии, что в общем модуле не будет собранного lsp и в fas будет вставлена строка с рекламой, которую я могу продать". Ну и плюнули мы на это дело.

Вот в этой открытой библиотеке можно было бы хоть бесконечно всё совершенствовать. Видит, например Дима_, что какая-то функция написана "по-бейсиковски" - берет её и переписывает "как надо". При условии, конечно, сохранения аргументов, результатов и принципов работы. А "обычные" пользователи-программисты могли бы такую библиотеку практически использовать, даже не копаясь в "кишочках". Или изучая их в порядке обучения.

Но нет такой идеи, которую не могут угробить энтузиасты...
ShaggyDoc вне форума  
 
Непрочитано 26.07.2013, 15:06
#13
gomer

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


Цитата:
Сообщение от ShaggyDoc Посмотреть сообщение
Святая простота....
Да нет, в смысле нет, не все так просто. Пользователю нужно дать как минимум два варианта: выход из программы или указание первой (второй, третьей) точки и как минимум три варианта: выход из программы, указание следующей точки и завершение выбора точек. К тому же пользователь скорей всего возжелает видеть, куда он тычет и к чему это в итоге приведет. В случае преждевременного аборта всю эту лабуду нужно удалять, так что библиотекой тут вряд ли обойдешься.
gomer вне форума  
 
Непрочитано 26.07.2013, 16:15
#14
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от Nitrogenium Посмотреть сообщение
Суть: пользователь вызывает программу, мышкой кликает несколько точек, после чего программа должна выдавать список точек ((x1 y1) (x2 y2)....), а так же отрисовывать полилинию (но без возможности рисовать дуговые элементы).
Напишите, если есть идеи.
Ещё один вариант по работе с точками.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Непрочитано 26.07.2013, 16:35
#15
ShaggyDoc

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


Цитата:
Пользователю нужно дать как минимум два варианта: выход из программы или указание первой (второй, третьей) точки и как минимум три варианта: выход из программы, указание следующей точки и завершение выбора точек. К тому же пользователь скорей всего возжелает видеть, куда он тычет и к чему это в итоге приведет. В случае преждевременного аборта всю эту лабуду нужно удалять, так что библиотекой тут вряд ли обойдешься.
Вот я и показываю, как это надежно сделать, без абортов. При желании функции ввода могут вызываться с ключевыми словами, опциями, и прочим. Функция *error* была когда-то единственным способом хоть как-то попытаться исправить последствия прерывания по ESC. Например, какие-то системные переменные восстановить. Но само нажатие ESC было "ломом против которого нет приема". Пока не появились функции vl-catch*.

Лично я считаю их самым ценным, что появилось в Visual Lisp за последнее десятилетие. Практически все остальные vl- можно перекрыть собственными Lisp-функциями, а ловушку на Lisp не сделаешь.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 26.07.2013, 23:09
#16
Nitrogenium

инженер
 
Регистрация: 02.03.2010
Санкт-Петербург
Сообщений: 69
<phrase 1=


Цитата:
Предотвращение вылета всей программы при нажатии ESC (но с разрешением его безопасного использования) надо выполнять с помощью ловушки ошибок. В основе ловушки - функции vl-catch-all-apply, vl-catch-all-error-p и vl-catch-all-error-message. Для их более удобного использования целесообразно написать функцию-аналог конструкции try... except ... end в других языках программирования. Такую функцию (ru-error-catch protected_expression on_error_expression) я уже несколько раз приводил на форуме.
Хотелось бы почитать про эти функции. Где их можно найти?
Nitrogenium вне форума  
 
Непрочитано 26.07.2013, 23:18
#17
Кулик Алексей aka kpblc
Moderator

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


Помимо стандартной литературы и "САПР на базе AutoCAD", можно глянуть и на http://autolisp.ru/2009/09/13/error-catch/ - я там поразвлекался немного на эту тему
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 27.07.2013, 00:48
#18
Nitrogenium

инженер
 
Регистрация: 02.03.2010
Санкт-Петербург
Сообщений: 69
<phrase 1=


Да уж..Столько всего написали тут..спасибо я почитаю...не знаю что сначала и читать, какой код разбирать. Наверно буду пытаться преобразовать функцию eea-vec, чтоб можно было точно указать точку (с привязкой например).
Nitrogenium вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Отрисовывание полилинии по щелчкам мыши с сохранением координат в список.



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Линии электрических соединений Shoorup Программирование 23 07.02.2015 15:13
Помощь по Лире Серега М Лира / Лира-САПР 52 28.05.2007 02:47