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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)

Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)

Ответ
Поиск в этой теме
Непрочитано 20.07.2008, 20:12
Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)
Red Nova
 
ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Торонто
Регистрация: 23.10.2007
Сообщений: 1,980

Со школы не ладится у меня с программированием. Все предметы щелкал, а на экзамене по информатике (Visual foxpro) программку типа суммирования столбцов списал у соседа (это уже в университете).
Не смотря на эте намерен научится писать программы для Автокада на лиспе, скачал книгу Хювенена, несколько примеров создания программ, но после получасового “смотрения” таких книг мое мышление явно притормаживает.
Решил пойти другим путем.
Нашел самый короткий лисп из моей коллекции, и прошу программистов с этого форума пошагово объяснить какой символ что означает. Надеюсь на вашу помощь.


Код:
[Выделить все]
(defun c:make-blocks-explodeable (/ adoc)
  (vl-load-com)
  (vla-startundomark
    (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
    ) ;_ end of vla-startundomark
  (vlax-for blk_def (vla-get-blocks adoc)
    (if (and (equal (vla-get-isxref blk_def) :vlax-false)
             (equal (vla-get-islayout blk_def) :vlax-false)
             ) ;_ end of and
      (vl-catch-all-apply '(lambda () (vla-put-explodable blk_def :vlax-true)))
      ) ;_ end of if
    ) ;_ end of vlax-for
  (vla-endundomark adoc)
  (princ)
  ) ;_ end of defun
_____________________________________________________________________________________________________________

Прошло много лет и топик теперь представляет из себя площадку для обучения азов программирования для многих начинающих.
Так что начинающие лиспогрызы приветствуются .
__________________
Блог

Последний раз редактировалось Red Nova, 12.07.2017 в 05:43.
Просмотров: 1965848
 
Непрочитано 22.07.2008, 23:34
#81
Кулик Алексей aka kpblc
Moderator

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


Я - не пользуюсь.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 23.07.2008, 06:18
#82
ShaggyDoc

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


Зачем блок-схемы? Это для первоклассников - чтоб на доске рисовать. Места много, толку мало. И не все выразишь. Алексей правильно делает - заготовка пустой функции, план в комментариях, потом реализация.

Цитата:
Получается три из пяти пунктов уже реализованы.
Ничего не реализовано. Читать надо внимательно. На первом этапе важен контроль ввода, обработка ситуаций нажатия ESC, пустого ввода. Да еще и надо предотвращение ошибок делать. Это можно оставить на усовершенствование, но забывать нельзя.
ShaggyDoc вне форума  
 
Непрочитано 23.07.2008, 08:18
#83
Кулик Алексей aka kpblc
Moderator

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


Позволю себе высказаться о последовательности разработки "сложения значений из 2 или более однострочных текстов или атрибутов":
1. Разработать или спереть функцию отлова ошибок (_ru-error-catch, _dwgru-error-catch)
2. Разработать или спереть функцию безошибочного указания примитива, возможно, с контролем возвращаемого типа. Сделать универсальной (т.е. дать возможность использовать и nentsel, при необходимости).
3. Решить раз и навсегда - функция будет обрабатывать 2 примитива? Или их надо указывать набором? В зависимости от этого будет немного меняться решение.
4. После п.3 написать часть получения текстовой строки (однострочного текста / атрибута) и перевода его в числовое значение. Ну и сложить. Сделать результат вычисления возвращаемым значением.
5. Написать общую функцию, которая загрузит все служебные функции и покажет результат.
5.1. Если результат надо выводить в однострочный текст, то потребуется функция создания однострочного текста. Подробности - самостоятельно (слишком много нюансов).
5.2. Если результат выводить в ком.строку или в alert - то все просто, но и это надо учитывать
---
6. Решить вопрос с предоставлением функции сторонним пользователям. Да и про себя, любимого, тоже забывать не след Возможно, разработать меню.
===
"Зачем так сложно!?" Затем, что функция безошибочного указания примитива, скорее всего, понадобится еще не одну сотню раз. И функция отлова ошибок.
Короче, "САПР на базе" в руки и вперед
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 23.07.2008, 09:35
#84
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,980
Отправить сообщение для Red Nova с помощью Skype™


ShaggyDoc,
Цитата:
Ничего не реализовано. Читать надо внимательно. На первом этапе важен контроль ввода, обработка ситуаций нажатия ESC, пустого ввода. Да еще и надо предотвращение ошибок делать. Это можно оставить на усовершенствование, но забывать нельзя.
Ну дай сперва хотя бы что-то самое простое разработать, а это все пока для меня слишком.
Пока мне хотелось бы понять как задачку от VVA дописать в самом простом виде. Полистал я хелп и лиспики разные тоже, но пока не понял какие функции надо использовать, чтобы построить полилинию по координатам относительно центра вставки.
Shoorup,
Цитата:
Да тут особо понимать то нечего... готовый код гораздо проще разобрать что и зачем нежели самому написать... во всяком случае мне...
Ну попробую объяснить что называется "от чайника чайнику"
Спасибо, я имел ввиду что не все эти функции пока знаю.
__________________
Блог
Red Nova вне форума  
 
Непрочитано 23.07.2008, 09:46
#85
Олег К.

Инженер-теплотехник
 
Регистрация: 17.08.2006
Смоленск
Сообщений: 307


>> Red Nova
Постройка полилинии по координатам:
- команда _.PLINE ;
- функция entmake ;
- vla-функции.
Выбирай.
Олег К. вне форума  
 
Непрочитано 23.07.2008, 09:48
#86
Кулик Алексей aka kpblc
Moderator

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


Red Nova, а ты как собираешься эту полилинию строить? Командой? entmake? vla?
Сильно подозреваю, что командой Поэтому - сначала получаешь центр, потом вычисление точек, потом не забыть osmode, команда _.pline, передать параметры, вернуть обратно osmode. Простейшая функция готова.
Переменные перевести в локальные обязательно! Потом можешь посмотреть на *error* и почти универсальный обработчик ошибок.
---
Не, это точно чат!
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 23.07.2008, 09:51
#87
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,980
Отправить сообщение для Red Nova с помощью Skype™


Олег К.,
Мне VVA пока запретил vla-функции .
Про команду _.PLINE не очень понял, разве в программу аутолисп можно вписать обычную команду?
Остается функция entmake. Почитаю про нее.
__________________
Блог
Red Nova вне форума  
 
Автор темы   Непрочитано 23.07.2008, 09:56
#88
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,980
Отправить сообщение для Red Nova с помощью Skype™


Кулик Алексей aka kpblc,
Цитата:
Red Nova, а ты как собираешься эту полилинию строить? Командой? entmake? vla?
Сильно подозреваю, что командой Поэтому - сначала получаешь центр, потом вычисление точек, потом не забыть osmode, команда _.pline, передать параметры, вернуть обратно osmode. Простейшая функция готова.
Переменные перевести в локальные обязательно! Потом можешь посмотреть на *error* и почти универсальный обработчик ошибок.
Напиши пожалуйста список функций, которые надо для этого применять, чтобы знать где копать.
__________________
Блог

Последний раз редактировалось Red Nova, 23.07.2008 в 10:08.
Red Nova вне форума  
 
Непрочитано 23.07.2008, 10:22
#89
Кулик Алексей aka kpblc
Moderator

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


getpoint, getdist (для указания ширины и высоты), getvar, setvar, command
Для вычисления точек пока используй напрямую setq и результат подставляй в command.
Как вариант, без учета поворота:
Код:
[Выделить все]
(defun red:command (/               center          osmode
                    width           height          low_left_point
                    low_right_point up_right_point  up_left_point
                    )
  (if (and (setq center (getpoint "\nЦентр колонны "))
           (setq width (getdist "\nШирина сечения колонны "))
           (setq height (getdist "\nВысота сечения колонны "))
           ) ;_ end of and
    (progn
      (setq osmode          (getvar "osmode")
            low_left_point  (list (- (car center) (* width 0.5))
                                  (- (cadr center) (* height 0.5))
                                  ) ;_ end of list
            low_right_point (list (+ (car low_left_point) width)
                                  (cadr low_left_point)
                                  ) ;_ end of list
            up_right_point  (list (car low_right_point)
                                  (+ (cadr low_right_point) height)
                                  ) ;_ end of list
            up_left_point   (list (- (car up_right_point) width)
                                  (cadr up_right_point)
                                  ) ;_ end of list
            ) ;_ end of setq
      (setvar "osmode" 0)
      (command "_.pline"          low_left_point     low_right_point
               up_right_point     up_left_point      "_c"
               ) ;_ end of command
      (setvar "osmode" osmode)
      ) ;_ end of progn
    ) ;_ end of if
  (princ)
  ) ;_ end of defun
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 23.07.2008, 10:27
#90
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,980
Отправить сообщение для Red Nova с помощью Skype™


Кулик Алексей aka kpblc, Если честно, ты мне обломал урок, Не буду смотреть пока твой код, я ведь хочу сам. Притворюсь, что ты ничего не выкладывал.

Цитата:
getpoint, getdist (для указания ширины и высоты), getvar, setvar, command
А вот это посмотрю.
__________________
Блог
Red Nova вне форума  
 
Непрочитано 23.07.2008, 10:39
#91
Кулик Алексей aka kpblc
Moderator

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


Код сделал прежде всего для анализа
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 23.07.2008, 11:10
1 | #92
VVA

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


Red Nova, Продолжим. Сейчас мы имеем такой код
Код:
[Выделить все]
(defun C:Колонна (/ width thickness base)
  (initget 7)
  (setq width (getreal "Введите ширину колонны <Выход>: "))
  (initget 7)
  (setq thickness (getreal "Введите толщину колонны <Выход>: "))
(setq base (getpoint "Введите точку вставки колонны <Выход>: ")) 
  ;продолжение
)
и
1. Мы не знаем vla-* функций (не можем обработать ESC)
2. Мы даже пока не знаем, что такое dxf коды (А ведь не знаем, правда?) Поэтому до того как
Цитата:
Остается функция entmake. Почитаю про нее.
нужно разобраться что такое dxf коды.
Остается пока
Цитата:
Про команду _.PLINE не очень понял, разве в программу аутолисп можно вписать обычную команду?
Можно! И именно так пока будем строить колонну.
Пару критических замечаний по существующему коду:
1. Мы ф-цией (initget 7) запрещаем пустой ввод. Поэтому здесь
"Введите ширину колонны <Выход>: " - <выход> не уместен.
А вот в getpointe мы пустой ввод не запрещаем, запрещать не будем, а выход заменим на 0,0.
Т.е. задача такая:
В случае нажатия ENTER на запрос getpoint присвоить переменной base точку с координатами 0,0
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 31.07.2008 в 10:41.
VVA вне форума  
 
Непрочитано 23.07.2008, 11:27
#93
ShaggyDoc

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


Анализ показал, что колонна всегда будет смотреть в одну сторону.


Цитата:
...разве в программу аутолисп можно вписать обычную команду
Так именно это и сделало AutoCAD таким популярным. Обычный инженер, зная команды AutoCAD, последовательность их выполнение и опции смог быстро научиться программировать. И миллионы негодяев этой лазейкой воспользовались.

Попробуйте-ка что-нибудь нарисовать на другом языке высокого уровня, и даже на LISP, но вне Автокада.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 23.07.2008, 12:58
#94
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,980
Отправить сообщение для Red Nova с помощью Skype™


VVA,
Ты хороший педагог.
Цитата:
. Мы даже пока не знаем, что такое dxf коды (А ведь не знаем, правда?)
Само собой не знаем.

Цитата:
Т.е. задача такая:
В случае нажатия ENTER на запрос getpoint присвоить переменной base точку с координатами 0,0
В программе построения графиков от по внешнему файлу Кулик Алексей aka kpblc, нашел функцию cond
Из справки

Цитата:
Cond
As shown, cond can be used as a case type function. It is common to use T as the last (default) test expression. Here's another simple example. Given a user response string in the variable s, this function tests the response and returns 1 if it is Y or y, 0 if it is N or n; otherwise nil.
(cond
((= s "Y") 1)
((= s "y") 1)
((= s "N") 0)
((= s "n") 0)
(t nil)
)
Думаю это означает, что Cond нам и нужен.
Думаю надо так
Код:
[Выделить все]
(cond
(getpoint "\Введите точку вставки колонны <0,0,0> :")
(t '(0. 0. 0.)))
То есть, учитывая еще твои замечания, а так же рекомендации от ShaggyDoc, лисп будет такой.

Код:
[Выделить все]
(defun C:Колонна (/ dimensionX dimensionY base)
(initget 7)
(setq dimensionX (getreal "Введите ширину колонны: "))
(initget 7)
(setq dimensionY (getreal "Введите толщину колонны: "))
(setq base 
            (cond
(getpoint "\Введите точку вставки колонны <0,0,0> :")
(t '(0. 0. 0.)))
) 
  ;продолжение
)
__________________
Блог
Red Nova вне форума  
 
Непрочитано 23.07.2008, 13:30
#95
Alaspher


 
Регистрация: 11.10.2004
e•burg
Сообщений: 755


если использовать cond, то надо немного подкорректировать:

Код:
[Выделить все]
(setq base 
            (cond
((getpoint "\Введите точку вставки колонны <0,0,0> :"))
(t '(0. 0. 0.)))
)
Alaspher вне форума  
 
Автор темы   Непрочитано 23.07.2008, 13:36
#96
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,980
Отправить сообщение для Red Nova с помощью Skype™


А в чем смысл сдвоенной скобки?
И зачем тут
Цитата:
(0. 0. 0.)
после последнего нуля ставят точку?
__________________
Блог

Последний раз редактировалось Red Nova, 23.07.2008 в 14:38.
Red Nova вне форума  
 
Непрочитано 23.07.2008, 14:04
#97
Alaspher


 
Регистрация: 11.10.2004
e•burg
Сообщений: 755


Функция cond обрабатывает аргументы, как списки. Если список, возвращает nil, переходит к следующему спску, если возвращено не nil, то полученное значение возвращается без обработки следующий списков. Список обрабатывается следующим образом - вычисляется первый элемент списка, если он не nil, то вычисляются все последующие элементы списка, последний вычисленный элемент возвращается. В случае:
Код:
[Выделить все]
(getpoint "\Введите точку вставки колонны <0,0,0> :")
первый элемент getpoint - он невычисляем и будет ошибка, в случае:
Код:
[Выделить все]
((getpoint "\Введите точку вставки колонны <0,0,0> :"))
первый элемент: (getpoint "\Введите точку вставки колонны <0,0,0> :") - его результат и будет возвращён (поскольку других нет).
Alaspher вне форума  
 
Непрочитано 23.07.2008, 14:05
#98
ShaggyDoc

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


Все-таки советую больше внимания уделить продумыванию алгоритма. Например, само рисование колонны. Вроде бы прямоугольник. Но из чего? Можно из отрезков, а можно полилинией. Можно и залитый, а можно и прозрачный. У колонны могут еще и свои "осики" быть. Двухветвевой она может быть или сплошной.

Приведу пример, как колонны в ruCAD рисуются в 2D. Сначала выбор из иллюстрированного меню (прилагаю скриншот). Там сразу выбирается типоразмер и вид колонны. Не обязательно самому именно такое меню делать, можно и просто в AutoCAD-овское встроить.

А вот протокол работы после выбора типа:

AutoCAD спрашивает:

Пролет=6000, Количество=1. Точка начала ряда [Пролет/Количество]<Выход>:К

То есть можем нарисовать и одну, и целый ряд с заданным пролетом. Можем сразу указать точку, а можем выбрать опции Пролет или Количество или просто нажать Enter и закончить работу.

Допустим, ввели опцию К (можно из автоматически сформированного контекстного меню, можно с клавиатуры).

Тогда спросит:
Количество [Указать]<1>:5

После ввода количества возобновляется допрос:

Пролет=6000, Количество=5. Точка начала ряда [Пролет/Количество]<Выход>:

Укажем точку. Тогда вопрос:

Направление ряда:

Здесь надо указать точку. После того рисуется целый ряд колонн (см. рис), и снова вопросы:

Пролет=6000, Количество=5. Точка начала ряда [Пролет/Количество]<Выход>:

То есть можно и еще несколько рядов указать. Или сделать пустой ввод и закончить программу.

Вот это как бы постановка задачи - что надо получить и как должно работать. Разумеется, могут быть и другие варианты.

А вот и программирование:

Всего одна строчка, вписываемая в меню.

Код:
[Выделить все]
 
(ru-draw-column "common\\ru-lib-column" "ru_column_2" 500 1000))
Всё делает одна функция, которой передаются аргументы, в частности размеры колонны.

Такой вызов легко модернизирует любая "тетка". Меняй 500 и 1000 на другие значения и будешь иметь кучу "команд".

Если же надо сплошную колонну 600х600, вызов немного другой:

Код:
[Выделить все]
 
(ru-draw-column "common\\ru-lib-column" "ru_column_1" 600 600))
И здесь возможны множество вариантов. Вся хитрость только в знании аргументов функции. И, разумеется, в обеспечении загрузки какой-то библиотеки, где эта функция определена. Но и для программирования мы также должны позаботиться о загрузке "кое-чего" стандартного. Например, (vl-load-com) сделать.

И вообще это совсем не обязательно для колонн, а для чего угодно подходит, где надо любое изображение с заданными габаритными размерами нарисовать сколько-то раз с заданным шагом. Картошку, например, рассадить.

Само же кодирование дело более техническое. Конечно, там нужны и знания и мастерство, но это всё-таки труд для "Microservs". Хорошую постановку задачи потом легче и реализовать в коде.

Последний раз редактировалось Кулик Алексей aka kpblc, 14.08.2008 в 16:08.
ShaggyDoc вне форума  
 
Автор темы   Непрочитано 23.07.2008, 14:19
#99
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,980
Отправить сообщение для Red Nova с помощью Skype™


ShaggyDoc,
Цитата:
Все-таки советую больше внимания уделить продумыванию алгоритма
Ты прав конечно же, VVA как раз по ходу дела и постановку задачи раскрывает, а-то я сразу не понял бы что к чему. Поэтапно понятнее.
__________________
Блог
Red Nova вне форума  
 
Автор темы   Непрочитано 23.07.2008, 18:03
#100
Red Nova

ՃԱՐՏԱՐԱԳԵՏ, Տ.Գ.Թ.
 
Регистрация: 23.10.2007
Торонто
Сообщений: 1,980
Отправить сообщение для Red Nova с помощью Skype™


VVA
Почитал немного про command
Из хелпа
Цитата:
The following example sets two variables pt1 and pt2 equal to two point values 1,1 and 1,5. It then uses the command function to issue the LINE command in the Command Reference and pass the two point values.
Command: (setq pt1 '(1 1) pt2 '(1 5))
(1 5)
Command: (command "line" pt1 pt2 "")
line From point:
To point:
To point:
Command: nil
Но прежде чем строить полилинию надо определить точки. Для этого надо ввести переменные pt1 pt2 pt3 pt4. Затем дать им значения, которые в математическом виде выглядят так:
Х pt1 =Х base – (dimensionX/2)
Y pt1 =Y base – (dimensionY/2)
И так далее для всех точек.
Теперь попробую это представить как лисп выражение
Код:
[Выделить все]
( setq pt1
            ( list ( 
                     ( - ( car base ) ( : dimensionX  2 ) )
                     ( - (cadr base ) ( : dimensionY  2 ) )
                   )
            )
 )
Ну и по тому же принципу для остальных точек.
Затем
Код:
[Выделить все]
 (command "pline" pt1 pt2 pt3 pt4)
Я прав?
__________________
Блог
Red Nova вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Вставка в таблицу поля, соотвествующего площади примитива Profan Готовые программы 272 06.06.2021 23:12
Сейсмозащита и сейсмоизоляция существующих, построенных зд. IANationalInformAgentstvo Прочее. Архитектура и строительство 216 20.01.2015 16:51
Мониторы LCD CRT Разное 94 17.06.2008 10:51
ЮМОР 2006 =) Perezz!! Разное 1122 04.01.2007 00:46