首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何访问AutoLisp中引用的变量数据?

如何访问AutoLisp中引用的变量数据?
EN

Stack Overflow用户
提问于 2018-12-26 15:21:17
回答 1查看 568关注 0票数 3

我很难访问存储在列表STPT1ENDPT1中的信息,它们是x(0)y(1)z(2)坐标。

例如,在得到点:(45.4529 21.6384 0.0)之后,当我使用Visual (-(NTH 1 STPT1) 0.5)进行检查时,我得到了一个真正的21.1384,但如下所示:

代码语言:javascript
运行
复制
(SETQ STPTP2 '((NTH 0 STPT1) (- (NTH 1 STPT1) 0.5) 0))

创建列表:

代码语言:javascript
运行
复制
((NTH 0 STPT1) (- (NTH 1 STPT1) 0.5) 0)

而不是:

代码语言:javascript
运行
复制
(45.4529 21.1384 0.0)

我的目标是同时创建两条平行线,每条平行线相距0.5个单位。

如何在列表STPT1ENDPT1的不同位置访问信息,然后在列表STPT2ENDPT2中分配它们?

代码语言:javascript
运行
复制
(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)
)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-26 16:07:18

当前问题

当前代码存在一些问题:

1.不平衡的父母关系

在代码的第5行中有一个太多的结束括号:

代码语言:javascript
运行
复制
(SETQ STPT2  '((NTH 0 STPT1)  (-(NTH 1 STPT1) 0.5) 0)))

上述表达式末尾的最后一个结束括号是关闭defun表达式,结果是在加载时计算其余表达式,而不是在计算函数时。

2.引用的可变数据

将下列表达式引用为文字表达式是错误的:

代码语言:javascript
运行
复制
(SETQ STPT2  '((NTH 0 STPT1)  (-(NTH 1 STPT1)  0.5) 0))
(SETQ ENDPT2 '((NTH 0 ENDPT1) (-(NTH 1 ENDPT1) 0.5) 0))

单引号后面的表达式不会由AutoLISP解释器计算,而是按“面值”计算。

这意味着不会对nth-函数进行计算,而是将其简单地解释为嵌套列表结构中的符号。有关文字表达式的更多信息,您可能希望参考我的教程描述撇号&引号函数

要构造变量(即非文字)数据的列表,应该使用list函数,例如:

代码语言:javascript
运行
复制
    (setq stpt2 (list (nth 0 stpt1) (- (nth 1 stpt1) 0.5) 0))

3.不必要的ActiveX

您不必要地加载Visual扩展(使用(vl-load-com)),但在代码中不使用此库中的任何函数。这是一个相对较小的问题,但仍然值得一提。

纠正上述问题并使用适当的缩进对代码进行格式化,我们有以下内容:

代码语言:javascript
运行
复制
(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语句即可避免此类错误:

代码语言:javascript
运行
复制
(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函数计算该方向:

代码语言:javascript
运行
复制
(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 (用户坐标系统)活动的坐标表示的点。

然而,与DXF组10 & 11相关联的用于绘图数据库中的LINE实体的点将被表示为相对于WCS (世界坐标系)。

我们可以使用AutoLISP trans函数在两个坐标系之间转换点:

代码语言:javascript
运行
复制
(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.引用常量数据

如果您有常量数据(例如,显式数值数据或字符串),您可以在代码中引用这些数据作为文字数据,从而避免了解释器计算listcons函数来构造数据结构的需要:

例如,

代码语言:javascript
运行
复制
(cons 0 "line")

可以成为:

代码语言:javascript
运行
复制
'(0 . "line")

因为0"line"都是常量数据,因此可能被标记为文本。

为此,我们有以下各点:

代码语言:javascript
运行
复制
(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)
)
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53933906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档