gpt4 book ai didi

lisp - 如何在 AutoLisp 中访问带引号的变量数据?

转载 作者:太空宇宙 更新时间:2023-11-03 18:41:40 25 4
gpt4 key购买 nike

我无法访问存储在列表 STPT1ENDPT1 中的信息,它们是 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 个单位的平行线。

如何访问列表STPT1ENDPT1中不同位置的信息,然后将它们分配到列表STPT2中结束点 2

(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。不平衡的括号

您代码第 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 Function 的教程。 .

要构建变量(即非文字)数据列表,您应该使用 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。用户输入验证

在继续对从用户那里获得的数据进行操作之前,您应该测试有效的用户输入:如果用户在没有提供点的情况下关闭提示,则对列表值的任何算术运算都会出错,因为这些值将是

您可以通过简单地使用 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(用户坐标系)在程序被评估时激活的。

但是,对于绘图数据库中的 LINE 实体,与 DXF 组 10 和 11 关联的点应相对于 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)
)

关于lisp - 如何在 AutoLisp 中访问带引号的变量数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53933906/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com