Текущие проблемы
Существует ряд проблем с вашим текущим кодом:
1.Несбалансированные скобки
В строке 5 вашего кода есть слишком много закрывающих скобок:
(SETQ STPT2 '((NTH 0 STPT1) (-(NTH 1 STPT1) 0.5) 0)))
Последняя закрывающая скобка в конце вышеприведенного выражения закрывает выражение defun
,в результате чего остальные выражения оцениваются при загрузке, а не при оценке функции.
2.Данные в кавычках
Вы неправильно цитируете следующие выражения как литеральные выражения:
(SETQ STPT2 '((NTH 0 STPT1) (-(NTH 1 STPT1) 0.5) 0))
(SETQ ENDPT2 '((NTH 0 ENDPT1) (-(NTH 1 ENDPT1) 0.5) 0))
Выражения, которые следуют за одинарной кавычкой, не будут оцениваться интерпретатором AutoLISP, а вместо этого будут приняты в'Номинальная стоимость'.
Это означает, что функции nth
и -
не будут оцениваться, а вместо этого будут интерпретироваться просто как символы в структуре вложенного списка.Для получения дополнительной информации о литеральных выражениях вы можете обратиться к моему руководству, описывающему функцию Apostrophe & Quote .
Чтобы составить список переменных (то есть не литеральных) данных, вам следуетиспользуйте функцию list
, например:
(setq stpt2 (list (nth 0 stpt1) (- (nth 1 stpt1) 0.5) 0))
3.Ненужный ActiveX
Вы без необходимости загружаете расширения Visual LISP ActiveX (используя (vl-load-com)
), но не используете никаких функций из этой библиотеки в своем коде.Это относительно небольшая проблема, но, тем не менее, стоит упомянуть.
Исправляя вышеуказанные проблемы и форматируя ваш код с соответствующим отступом, у нас есть следующее:
(defun c:curbyourenthusiasm ( / stpt1 endpt1 stpt2 endpt2 )
(setq stpt1 (getpoint "\nSpecify start point: "))
(setq endpt1 (getpoint stpt1 "\nSpecify end point: "))
(setq stpt2 (list (nth 0 stpt1) (- (nth 1 stpt1) 0.5) 0))
(setq endpt2 (list (nth 0 endpt1) (- (nth 1 endpt1) 0.5) 0))
(setq top (entmake (list (cons 0 "line") (cons 10 stpt1) (cons 11 endpt1) (cons 8 "concrete"))))
(setq bottom (entmake (list (cons 0 "line") (cons 10 stpt2) (cons 11 endpt2) (cons 8 "concrete"))))
(princ)
)
Этот код будеттеперь успешно запускаются, но есть ряд возможных улучшений:
Возможные улучшения
1.Проверка пользовательского ввода
Перед выполнением обработки данных, полученных от пользователя, следует проверить действительный ввод пользователя: если пользователь отклоняет запросы без указания точки, любые арифметические операции со значениями списка будут ошибочными, поэтомузначения будут nil
.
Вы можете избежать таких ошибок, просто используя оператор if
:
(defun c:curbyourenthusiasm ( / ep1 sp1 )
(if
(and
(setq sp1 (getpoint "\nSpecify start point: "))
(setq ep1 (getpoint "\nSpecify end point: " sp1))
)
(progn
;; Continue with program operations
)
)
(princ)
)
2.Изменение угла линии
В настоящее время ваш код всегда будет смещать вторую линию в отрицательном направлении y, что приведет к изменению межстрочного интервала при изменении угла линии - когда угол линии вертикальный,две линии будут перекрываться.
Чтобы избежать этого, вы можете использовать функцию polar
для вычисления смещения точки на заранее определенное расстояние от указанных начальной и конечной точек в направлении, перпендикулярном углу линии, которое выможно рассчитать с помощью функции angle
:
(defun c:curbyourenthusiasm ( / ang ep1 ep2 sp1 sp2 )
(if
(and
(setq sp1 (getpoint "\nSpecify start point: "))
(setq ep1 (getpoint "\nSpecify end point: " sp1))
)
(progn
(setq ang (- (angle sp1 ep1) (/ pi 2))
sp2 (polar sp1 ang 0.5)
ep2 (polar ep1 ang 0.5)
)
;; Continue with program operations
)
)
(princ)
)
3.Учет UCS
Функция getpoint
возвращает точки, координаты которых выражены относительно текущей UCS (пользовательской системы координат), активной во время оценки программы.
Однакоожидается, что точки, связанные с группами 10 и 11 DXF для объекта LINE
в базе данных чертежей, будут выражены относительно WCS (Всемирной системы координат).
Мы можем преобразовать точки между двумя системами координат, используяФункция AutoLISP trans
:
(defun c:curbyourenthusiasm ( / ang ep1 ep2 sp1 sp2 )
(if
(and
(setq sp1 (getpoint "\nSpecify start point: "))
(setq ep1 (getpoint "\nSpecify end point: " sp1))
)
(progn
(setq ang (- (angle sp1 ep1) (/ pi 2))
sp2 (trans (polar sp1 ang 0.5) 1 0)
ep2 (trans (polar ep1 ang 0.5) 1 0)
sp1 (trans sp1 1 0)
ep1 (trans ep1 1 0)
)
;; Continue with program operations
)
)
(princ)
)
4.Заключение в кавычки константных данных
Если у вас есть постоянные данные (например, явные числовые данные или строки), вы можете цитировать такие данные как буквальные данные в коде, избегая необходимости интерпретатора для оценки list
и cons
функции для построения структур данных:
Например:
(cons 0 "line")
Может стать:
'(0 . "line")
С 0
и "line"
являются постоянными данными и поэтому могут быть помечены как литералы.
Реализуя все вышеперечисленное, мы имеем следующее:
(defun c:curbyourenthusiasm ( / ang ep1 ep2 sp1 sp2 )
(if
(and
(setq sp1 (getpoint "\nSpecify start point: "))
(setq ep1 (getpoint "\nSpecify end point: " sp1))
)
(progn
(setq ang (- (angle sp1 ep1) (/ pi 2))
sp2 (trans (polar sp1 ang 0.5) 1 0)
ep2 (trans (polar ep1 ang 0.5) 1 0)
sp1 (trans sp1 1 0)
ep1 (trans ep1 1 0)
)
(entmake (list '(0 . "LINE") '(8 . "concrete") (cons 10 sp1) (cons 11 ep1)))
(entmake (list '(0 . "LINE") '(8 . "concrete") (cons 10 sp2) (cons 11 ep2)))
)
)
(princ)
)