Как получить доступ к данным в кавычках в AutoLisp? - PullRequest
0 голосов
/ 26 декабря 2018

У меня проблемы с доступом к информации, хранящейся в списках STPT1 и ENDPT1, которые являются x(0), y(1) и z(2) координатами.

Например, после получения балла: (45.4529 21.6384 0.0) когда я проверяю с помощью Visual LISP (-(NTH 1 STPT1) 0.5), я получаю REAL 21.1384, но следующее:

(SETQ STPTP2 '((NTH 0 STPT1) (- (NTH 1 STPT1) 0.5) 0))

создает список:

((NTH 0 STPT1) (- (NTH 1 STPT1) 0.5) 0)

вместо:

(45.4529 21.1384 0.0)

Моя цель состоит в том, чтобы одновременно создать две параллельные линии, которые находятся на расстоянии 0,5 единицы друг от друга.

Как получить доступинформацию в разных позициях списков STPT1 и ENDPT1, а затем назначить их в списках STPT2 и ENDPT2?

(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  '((NTH 0 STPT1)  (-(NTH 1 STPT1) 0.5) 0))
(SETQ ENDPT2 '((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 Ответ

0 голосов
/ 26 декабря 2018

Текущие проблемы

Существует ряд проблем с вашим текущим кодом:

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)
)

...