chi*_*ogi 3 lisp autocad autolisp
我无法访问存储在列表中的信息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))
Run Code Online (Sandbox Code Playgroud)
创建列表:
((NTH 0 STPT1) (- (NTH 1 STPT1) 0.5) 0)
Run Code Online (Sandbox Code Playgroud)
代替:
(45.4529 21.1384 0.0)
Run Code Online (Sandbox Code Playgroud)
我的目标是同时创建两条相互间隔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)
)
Run Code Online (Sandbox Code Playgroud)
您当前的代码存在许多问题:
在代码的第5行上有一个太多的右括号:
(SETQ STPT2 '((NTH 0 STPT1) (-(NTH 1 STPT1) 0.5) 0)))
Run Code Online (Sandbox Code Playgroud)
上面表达式末尾的最后一个右括号是关闭defun表达式,导致剩余的表达式在加载时计算,而不是在计算函数时.
您错误地将以下表达式引用为文字表达式:
(SETQ STPT2 '((NTH 0 STPT1) (-(NTH 1 STPT1) 0.5) 0))
(SETQ ENDPT2 '((NTH 0 ENDPT1) (-(NTH 1 ENDPT1) 0.5) 0))
Run Code Online (Sandbox Code Playgroud)
AutoLISP解释器不会评估单引号后面的表达式,而是采用"面值".
这意味着将不会评估nth和-函数,而是将其简单地解释为嵌套列表结构中的符号.有关文字表达式的更多信息,您可能希望参考我的描述Apostrophe和引用函数的教程.
要构造变量(即非文字)数据列表,您应该使用该list函数,例如:
(setq stpt2 (list (nth 0 stpt1) (- (nth 1 stpt1) 0.5) 0))
Run Code Online (Sandbox Code Playgroud)
您不必要地加载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)
)
Run Code Online (Sandbox Code Playgroud)
此代码现在将成功运行,但有许多可能的改进:
在继续操作从用户获得的数据之前,您应该测试有效的用户输入:如果用户在不提供点的情况下解除提示,则对列表值的任何算术运算都将出错,因为这样的值将是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)
)
Run Code Online (Sandbox Code Playgroud)
目前,您的代码将始终偏移负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)
)
Run Code Online (Sandbox Code Playgroud)
该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)
)
Run Code Online (Sandbox Code Playgroud)
如果您有常量数据(例如显式数值数据或字符串),您可以在代码中引用像文字数据这样的数据,从而避免需要解释器来评估构造数据结构的函数list和cons函数:
例如:
(cons 0 "line")
Run Code Online (Sandbox Code Playgroud)
可以变成:
'(0 . "line")
Run Code Online (Sandbox Code Playgroud)
因为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)
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
238 次 |
| 最近记录: |