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

Вернуться   Форум 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.
Просмотров: 1972505
 
Непрочитано 06.10.2015, 17:03
#2721
Кулик Алексей aka kpblc
Moderator

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


Neo, теоречически - получаешь список первых элементов, убираешь дубликаты, а потом проходишь по всему списку и группируешь остатки.

----- добавлено через ~6 мин. -----
Как пример:
Код:
[Выделить все]
 (defun test (lst / res)
  (mapcar
    (function
      (lambda (x)
        (if (member (car x) (mapcar (function car) res))
          (setq res (subst (cons (car x) (append (list (cdr (assoc (car x) res))) (list (cdr x))))
                           (assoc (car x) res)
                           res
                           ) ;_ end of subst
                ) ;_ end of setq
          (setq res (cons x res))
          ) ;_ end of if
        ) ;_ end of lambda
      ) ;_ end of function
    lst
    ) ;_ end of mapcar
  res
  ) ;_ end of defun
;|
_$ (test '(("1" "a" "b") ("1" "c" "d") ("2" "e" "f")))
(("2" "e" "f") ("1" ("a" "b") ("c" "d")))
|;
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 07.10.2015, 14:39
#2722
Neo


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


Спасибо. буду разбираться. А объясни использование (function (lambda вместо '(lambda. При добавлении function компилятор оптимизирует функцию, как и где это заметить?
Neo вне форума  
 
Непрочитано 07.10.2015, 15:04
#2723
Кулик Алексей aka kpblc
Moderator

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


Где проверить: http://autolisp.ru/2009/09/20/execution-speed-check/
И у применения function есть еще один плюс: можно поставить точку останова внутри анонимной функции. Иногда полезно.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 08.10.2015, 10:04
#2724
frostmourn


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


Доброго дня. Можно ли как-нибудь без полного открытия файла чертежа достать из него системную переменную? Пока делаю так
Код:
[Выделить все]
 (vla-open (vla-get-documents (vlax-get-acad-object)) (vla-get-path <тут название>) :vlax-true)
и далее получение переменной и закрытие.
Но для больших файлов долго выходит, хочется как через ODBX или наподобие, только чтоб с переменными работало.
frostmourn вне форума  
 
Непрочитано 08.10.2015, 10:08
#2725
Кулик Алексей aka kpblc
Moderator

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


Ну так открывай через ObjectDBX, получай указатель на объект документа, а потом (vla-getvariable УказательНаДокумент НазваниеПеременной)
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 08.10.2015, 14:20
#2726
frostmourn


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


Так он (ODBX) не даёт же доступа к системным переменным?..
И при попытке сделать (vla-getvariable ...) говорит - неизвестное имя: GetVariable.

Последний раз редактировалось frostmourn, 12.10.2015 в 14:56.
frostmourn вне форума  
 
Непрочитано 15.10.2015, 09:38
#2727
Pavel_GP

Инженер-гидрограф
 
Регистрация: 15.09.2011
г.г. Ленинград
Сообщений: 170


Привет.
Есть код автор ув. akka_KPbIC
Код:
[Выделить все]
  (defun test (/ _kpblc-conv-list-to-2dpoints _kpblc-conv-vla-to-list ent bit coords idx)
  (defun _kpblc-conv-list-to-2dpoints (lst / res)
    (cond
      ((not lst)
       nil
       )
      (t
       (setq res (cons (list (car lst)
                             (if (cadr lst)
                               (cadr lst)
                               0.
                               ) ;_ end of if
                             ) ;_ end of list
                       (_kpblc-conv-list-to-2dpoints (cddr lst))
                       ) ;_ end of cons
             ) ;_ end of setq
       )
      ) ;_ end of cond
    res
    ) ;_ end of defun

  (defun _kpblc-conv-vla-to-list (value / res)
    (cond
      ((listp value)
       (mapcar (function _kpblc-conv-vla-to-list) value)
       )
      ((= (type value) 'variant)
       (_kpblc-conv-vla-to-list (vlax-variant-value value))
       )
      ((= (type value) 'safearray)
       (if (>= (vlax-safearray-get-u-bound value 1) 0)
         (_kpblc-conv-vla-to-list (vlax-safearray->list value))
         ) ;_ end of if
       )
      ((and (= (type value) 'vla-object)
            (vlax-property-available-p value 'count)
            ) ;_ end of and
       (vlax-for sub value
         (setq res (cons sub res))
         ) ;_ end of vlax-for
       ) ;_ end of cond
      (t value)
      ) ;_ end of cond
    ) ;_ end of defun

  (if (and (= (type (setq ent (vl-catch-all-apply
                                (function
                                  (lambda ()
                                    (car (entsel "\nSelect LWPolyline <Cancel> : "))
                                    ) ;_ end of LAMBDA
                                  ) ;_ end of function
                                ) ;_ end of VL-CATCH-ALL-APPLY
                          ) ;_ end of setq
                    ) ;_ end of type
              'ename
              ) ;_ end of =
           (setq ent (vlax-ename->vla-object ent))
           (= (vla-get-objectname ent) "AcDbPolyline")
           ) ;_ end of and
    (progn
      (setq bit 0
            idx 0
            ) ;_ end of setq
      (foreach vertex (_kpblc-conv-list-to-2dpoints (_kpblc-conv-vla-to-list (vla-get-coordinates ent)))
;;; Здесь ты делаешь то, что считаешь нужным
        (setq coords (cons (cond
                             ((= bit 0) (list (+ (car vertex) 10.) (cadr vertex)))
                             ((= bit 1) (list (car vertex) (+ (cadr vertex) 10.)))
                             ((= bit 2) (list (- (car vertex) 10.) (cadr vertex)))
                             ((= bit 3) (list (car vertex) (- (cadr vertex) 10.)))
                             ) ;_ end of cond
                           coords
                           ) ;_ end of cons
              bit    (if (> bit 2)
                       0
                       (1+ bit)
                       ) ;_ end of if
              ) ;_ end of setq
        ) ;_ end of foreach
      (setq coords (apply (function append) (reverse coords)))
;;; И теперь чохом назначаешь все координаты в полилинию
      (vla-put-coordinates ent
                           (vlax-make-variant
                             (vlax-safearray-fill
                               (vlax-make-safearray
                                 vlax-vbdouble
                                 (cons 0 (1- (length coords)))
                                 ) ;_ end of vlax-make-safearray
                               coords
                               ) ;_ end of vlax-safearray-fill
                             ) ;_ end of vlax-make-variant
                           ) ;_ end of vla-put-Coordinates
      (vla-update ent)
      ) ;_ end of progn
    ) ;_ end of if
  ) ;_ end of defun
, тему начали тут http://forum.dwg.ru/showthread.php?t=65178&page=2
По размыслив почитав vla-семейства, попытаюсь написать, как я понимаю твое решение:
1. Создал две функции преобразований списка координат в список чисел и обратно.
2. Далее, выбираем полилинию и если это полилиния, то идем далее
3. Потом не плохой ухват, запуск цикла функцией foreach и тут внутри цикла есть доп.вопросики:
а. Внутри цикла это не пример? а необходимый код?
б. Из vertex я могу достать X и Y, они мне нужны для корректировки, у меня будет формула их изменения.
4. После того как координаты изменились у вершин полилинии можно строить новую полилинию, но вопросик где прописано постройка новой полилинии? Вроде пока всё.

Да, чуть не забыл, кто не в курсе вопрос стоял в том, что есть полилиния (простая), изменяя координаты вершин полилинии (любые математические действия), строим рядом новую полилинию.
Спс.
__________________
AutoCAD Civil 3D 2012г. 32-разрядная.
Pavel_GP вне форума  
 
Непрочитано 15.10.2015, 10:20
#2728
Sleekka

-
 
Регистрация: 24.07.2005
Москва
Сообщений: 1,335


Скажите, что сделать то нужно.
Sleekka вне форума  
 
Непрочитано 15.10.2015, 10:53
#2729
Pavel_GP

Инженер-гидрограф
 
Регистрация: 15.09.2011
г.г. Ленинград
Сообщений: 170


Цитата:
Сообщение от Sleekka Посмотреть сообщение
Скажите, что сделать то нужно.
Есть полилиния, необходимо построить новую, изменяя координаты вершин исходной полилинии. Координаты изменяются по формуле (какие-то математические действия с координатой X и Y). Полилиния м.б. много вершинная от 2 до ...
Вот ещё что, у меня полилиния нового формата не LWpolyline, а просто Polyline
При выборе полилинии равенство подтверждается
Код:
[Выделить все]
 (= (vla-get-objectname ent) "AcDbPolyline")
.

Идем далее
Код:
[Выделить все]
 (setq coords (cons (cond
                             ((= bit 0) (list (+ (car vertex) 10.) (cadr vertex)))
                             ((= bit 1) (list (car vertex) (+ (cadr vertex) 10.)))
                             ((= bit 2) (list (- (car vertex) 10.) (cadr vertex)))
                             ((= bit 3) (list (car vertex) (- (cadr vertex) 10.)))
                             ) ;_ end of cond
                           coords
                           ) ;_ end of cons
              bit    (if (> bit 2)
                       0
                       (1+ bit)
                       ) ;_ end of if
              ) ;_ end of setq
тут я понял ты привел пример получения новых координат вершин, тогда вопрос:
bit почему именно до 3, какую роль они играют в твоем решении (примера)? В моем случае одна формула будет для всех X и одна для всех Y
__________________
AutoCAD Civil 3D 2012г. 32-разрядная.

Последний раз редактировалось Pavel_GP, 15.10.2015 в 13:02.
Pavel_GP вне форума  
 
Непрочитано 15.10.2015, 14:26
1 | #2730
Кулик Алексей aka kpblc
Moderator

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


Pavel_GP, так тебе надо строить новую или менять существующую? Разница принципиальная: у меня код меняет существующую полилинию. Попробую ответить по пунктам
Цитата:
Сообщение от Pavel_GP Посмотреть сообщение
1. Создал две функции преобразований списка координат в список чисел и обратно.
Ага. Можно было обойтись без функций, выполняя соответствующие преобразования сразу - но эти функции у меня уже бог знает сколько времени используются, мне проще было их прикрутить.
Цитата:
Сообщение от Pavel_GP Посмотреть сообщение
2. Далее, выбираем полилинию и если это полилиния, то идем далее
Верно
Цитата:
Сообщение от Pavel_GP Посмотреть сообщение
3. Потом не плохой ухват, запуск цикла функцией foreach и тут внутри цикла есть доп.вопросики:
Не совсем так. Запускается foreach, объявляется итератор (ну типа счетчика) и сразу вычисляется список, по которму будет выполняться проходка. Вычисление выполняется только при старте foreach.
Цитата:
Сообщение от Pavel_GP Посмотреть сообщение
Внутри цикла это не пример? а необходимый код?
Пополам. Результат вычислений где-то надо бы сохранить, для этого служит coords
Цитата:
Сообщение от Pavel_GP Посмотреть сообщение
Из vertex я могу достать X и Y, они мне нужны для корректировки, у меня будет формула их изменения.
Да легко!
Цитата:
Сообщение от Pavel_GP Посмотреть сообщение
После того как координаты изменились у вершин полилинии можно строить новую полилинию, но вопросик где прописано постройка новой полилинии? Вроде пока всё.
Почти. Вычисленные новые координаты приводятся в вид variant (т.н. безопасный массив) и подставляются как координаты старой полилинии. В результате она получит новые координаты вершин. Ширина, кривизна и проч. не меняются
Цитата:
Сообщение от Pavel_GP Посмотреть сообщение
bit почему именно до 3, какую роль они играют в твоем решении (примера)? В моем случае одна формула будет для всех X и одна для всех Y
Это как раз пример. Если у тебя вычисление новой координаты выполняется какой-то функцией типа (eval-new-coords x y), то и пиши (setq coords (cons (eval-new-coords (car vertex) (cadr vertex)) coords)) - этого по идее должно быть достаточно.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 15.10.2015, 14:55
#2731
Pavel_GP

Инженер-гидрограф
 
Регистрация: 15.09.2011
г.г. Ленинград
Сообщений: 170


Спасибо, что разжевал всё подробно

Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
надо строить новую
Верно новую.

Будут вопросики отпишу. Пока тестю.
__________________
AutoCAD Civil 3D 2012г. 32-разрядная.
Pavel_GP вне форума  
 
Непрочитано 15.10.2015, 15:03
#2732
Кулик Алексей aka kpblc
Moderator

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


Если новую, то сразу вопросы: слой, тип и вес линии откуда брать? Elevation, Thickness, слой? Как учитывать кривизну элементов? Предустановленную ширину сегментов (возможно, переменную)?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 15.10.2015, 15:50
#2733
Pavel_GP

Инженер-гидрограф
 
Регистрация: 15.09.2011
г.г. Ленинград
Сообщений: 170


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Если новую, то сразу вопросы: слой, тип и вес линии откуда брать? Elevation, Thickness, слой? Как учитывать кривизну элементов? Предустановленную ширину сегментов (возможно, переменную)?
слой тот же, тип линии CONTI, вес линии 0.3, цвет Красный.
Подскажи плз функцию выбора, как в функции offset, когда пользователю предоставляется выбор кликнуть мышкой с какой стороны построить. У меня сложный расчет изменения координат вершин, (я пытаюсь создать программку на подобие оффсета, только расстояние у меня будет не на плоскости на эллипсоиде, поэтому и приходится формулой преобразовывать координаты вершин), будет задействован угол (перпендикуляр к полилинии).
__________________
AutoCAD Civil 3D 2012г. 32-разрядная.

Последний раз редактировалось Pavel_GP, 15.10.2015 в 16:33.
Pavel_GP вне форума  
 
Непрочитано 15.10.2015, 16:43
#2734
Кулик Алексей aka kpblc
Moderator

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


Во-первых, есть метод vla-offset. Во-вторых, для вычисления первой и второй производной в любой точке любой кривой есть функции vlax-curve-getfirstderiv и vlax-curve-getsecondderiv. Описание есть в справке
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 16.10.2015, 08:45
#2735
Pavel_GP

Инженер-гидрограф
 
Регистрация: 15.09.2011
г.г. Ленинград
Сообщений: 170


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
метод vla-offset.
Все хорошо, но мне не нужно чтоб при вводе смещения объект сразу смещался, я задаю величину смещения для дальнейшей обработки его в формуле вычисления координат вершин.

Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
функции vlax-curve-getfirstderiv и vlax-curve-getsecondderiv
С помощью этих функций можно вычислить координаты вершин, только не понимаю, как мне их применить?, и зачем мы уже их вычислили

С можешь отредактировать нижнюю часть своего решения? ( см. #2726)

Работаю пока над основной формулой вычисления внутри foreach
__________________
AutoCAD Civil 3D 2012г. 32-разрядная.

Последний раз редактировалось Pavel_GP, 16.10.2015 в 08:56.
Pavel_GP вне форума  
 
Непрочитано 16.10.2015, 10:08
#2736
Кулик Алексей aka kpblc
Moderator

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


Так создавай новую полилинию, через vla-addlightweightpolyline, задавай полученному примитиву нужные свойства. Принцип не изменится: получить примитив, собрать координаты, создать новый.
P.S. В принципе, можно и через ename сделать - возможно, так даже будет более интересно.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 16.10.2015, 10:51
#2737
Pavel_GP

Инженер-гидрограф
 
Регистрация: 15.09.2011
г.г. Ленинград
Сообщений: 170


Спс. тут я понял.
Вопрос:
Мне необходимо получение угла( это все нужно в формулу получения новых координат вершин, которая определяется внутри foreach), после выбора стороны смещения
Код:
[Выделить все]
 (setq	pt
		 (getpoint "\n Уажите точку, определяющую сторону смещения"
		 )
	  ) ;_end setq pt
Это угол будет меняться от сегмента к сегменту пока не дойдет до последней вершины. Угол равен + - 90° (зависти от стороны смещения) от направления сегмента полилинии
и куда его вставить в твое решение?
__________________
AutoCAD Civil 3D 2012г. 32-разрядная.
Pavel_GP вне форума  
 
Непрочитано 19.10.2015, 14:36
#2738
Pavel_GP

Инженер-гидрограф
 
Регистрация: 15.09.2011
г.г. Ленинград
Сообщений: 170


Привет.
Код:
[Выделить все]
 (setq n 0)
	      (while (/= (nth (1+ n) xy_v) nil)
		(setq angl_1 (append
			     angl_1
			     (list (- pi
				      (angle (nth n xy_v) (nth (1+ n) xy_v))
				   )
			     )
			   )
		      n	   (1+ n)
		) ;_end setq
	      ) ;_end while
, где xy_v список координат ( (x1 y1) (x2 y2) .... (xn yn))
Как составить такой вариант список углов (угол (/ (угол+угол1) 2.) (/ (угол1+угол2) 2.) .... уголn)
Спс.
__________________
AutoCAD Civil 3D 2012г. 32-разрядная.

Последний раз редактировалось Pavel_GP, 19.10.2015 в 14:54.
Pavel_GP вне форума  
 
Непрочитано 19.10.2015, 14:50
#2739
Кулик Алексей aka kpblc
Moderator

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


(append angl_1 (list (car angl_1)))
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.10.2015, 16:46
#2740
Pavel_GP

Инженер-гидрограф
 
Регистрация: 15.09.2011
г.г. Ленинград
Сообщений: 170


Это замыкать (1 2 3 4 1)
Я просил такой тип (a (/ (a+b) 2.) (/ (b+c) 2.) ... (/ (g+n) 2.) n), где второй список это среднее между 1 и 2 углами и т.д. а последний угол это просто угол.
Пример: Полилиния из двух сегментов список такой (a ((a+b)/2) b) (три угла)
Полилиния из пяти сегментов список такой (a ((a+b)/2) ((b+c)/2) ((c+d)/2) ((d+e)/2) e) (шесть углов)
__________________
AutoCAD Civil 3D 2012г. 32-разрядная.

Последний раз редактировалось Pavel_GP, 19.10.2015 в 16:55.
Pavel_GP вне форума  
Ответ
Вернуться   Форум 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