找不到线的中点
大家好,今天,我尝试了李Mac的一些编码风格——通过组合cond和not函数。我想我理解他这样做的原因——在代码中切换和找到断点很容易。在我的例子中是这样的:
Midpoint of the line not found.
问题是我不明白它出了什么问题,所以我运行了VLIDE并观察了一些变量:
LOG Watch
...............
MIDPT = (2377.57 -1262.93 0.0)
ENDPT2 = (3345.54 -1666.0 0.0)
ENDPT1 = (1409.6 -859.868 0.0)
LINE = ((1409.6 -859.868 0.0) (3345.54 -1666.0 0.0))
ENTITYTYPE = "LWPOLYLINE"
ENT = (<Entity name: 7ff6d2304ea0> (1812.88 -1048.75 0.0))
CENSSBOX = (2556.4 1934.71 0.0)
SSBOX = ((1891.74 1157.88 0.0) (3221.06 2711.53 0.0))
...............
基本上,我试图将SS从“Censbox”移动到“MIDPT”点变量。我知道我有两种不同的方法来找到这些点。
事实上,我单独测试了变量-使用POINT命令我成功地绘制了它们的正确位置-但结合在一起用于move命令密码告诉我要迷路。
这里是顺便说一句:
; Moves selection from its center to the midpoint of the picked LINE or PLINE's segment
(defun c:test ( / pdm ss ssbox censsbox ent entitytype line endpt1 endpt2 midpt )
(vl-load-com)
(setq pdm (getvar 'PDMODE))
(setvar 'PDMODE 35)
(while
(cond
( (not (and (princ "\nSelect objects to move") (setq ss (ssget "_:L"))))
(princ "\nNothing selected.")
)
( (not (setq ssbox (LM:ssboundingbox ss)))
(princ "\nUnable to calculate bounding box for selection.")
)
( (not (setq censsbox (apply 'mapcar (cons '(lambda ( a b ) (/ (+ a b) 2.0)) ssbox)) ))
(princ "\nUnable to find bounding box's centroid.")
)
( (not (setq ent (entsel "\nPick a line or a polyline's segment")))
(princ "\nMissed.. Try again!")
)
( (not (setq entitytype (cdr (assoc 0 (entget (car ent))))) )
(princ "\nEntitytype not found.")
)
(
(progn
(setq line (get_ends ent))
(setq endpt1 (carline))
(setq endpt2 (cadrline))
(setq midpt (mid endpt1 endpt2))
)
(princ "\nMidpoint of the line not found.")
)
(
(progn
(vl-cmdf "_.move" ss ""
"_non" censsbox
"_non" midpt
)
(princ (strcat "\nThis time you picked \"" entitytype "\" entity! " ))
)
)
);cond
(setvar 'PDMODE pdm)
);while
(princ)
)
; (command "_.POINT" endpt1 )
; (command "_.POINT" endpt2 )
; (command "_.POINT" censsbox )
; (command "_.POINT" midpt )
(defun mid (p1 p2)
(mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2.0)) p1 p2)
)
; Stefan BMR
(defun get_ends (e / o p p1 p2 b)
(setq o(car e)
b(eq (cdr (assoc 0 (entget o))) "LWPOLYLINE")
p(vlax-curve-getparamatpoint
o
(vlax-curve-getclosestpointto o (trans (cadr e) 1 0))
)
p1 (if b
(fix p)
(vlax-curve-getstartparam o)
)
p2 (if b
(1+ p1)
(vlax-curve-getendparam o)
)
)
(if (> (- p2 p) (- p p1))
(list
(trans (vlax-curve-getpointatparam o p1) 0 1)
(trans (vlax-curve-getpointatparam o p2) 0 1)
)
(list
(trans (vlax-curve-getpointatparam o p2) 0 1)
(trans (vlax-curve-getpointatparam o p1) 0 1)
)
)
)
(defun LM:listmid ( lst )
((lambda ( n ) (mapcar '(lambda ( x ) (/ x n)) (apply 'mapcar (cons '+ lst)))) (length lst))
)
;; Selection Set Bounding Box-Lee Mac
;; Returns a list of the lower-left and upper-right WCS coordinates of a
;; rectangular frame bounding all objects in a supplied selection set.
;; s - Selection set for which to return bounding box
(defun LM:ssboundingbox ( s / a b i m n o )
(repeat (setq i (sslength s))
(if
(and
(setq o (vlax-ename->vla-object (ssname s (setq i (1- i)))))
(vlax-method-applicable-p o 'getboundingbox)
(not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list o 'a 'b))))
)
(setq m (cons (vlax-safearray->list a) m)
n (cons (vlax-safearray->list b) n)
)
)
)
(if (and m n)
(mapcar '(lambda ( a b ) (apply 'mapcar (cons a b))) '(min max) (list m n))
)
)
提示:(setq midpt(mid endpt1 endpt2))将返回一个非nil值,以验证cond test表达式。 嗨,李,
我真的不理解这个问题,在“Log Watch”上我清楚地看到“midpt”变量返回(2377.57-1262.93 0.0)。
我假设这是一个点坐标。
编辑:
我发现了问题。。。
(
(not
(progn
(setq line (get_ends ent))
(setq endpt1 (carline))
(setq endpt2 (cadrline))
(setq midpt (mid endpt1 endpt2))
)
)
(princ "\nMidpoint of the line not found.")
)
我需要仔细研究cond的工作原理。
我在entsel部分的第二个问题上卡住了,我要试一下。 如果(cond)测试序列中的任何测试具有非零返回,(cond)停止评估其余的条件测试。即,如果设置了midpt,则永远不会执行move命令
-大卫 谢谢David,
所以整个过程都是这样的吗
(cond
( (not (Stuff to do #1))) ; evaluate arguments from user and continue if TRUE next to #2
(princ "\nStuff to do #1 are not done, do them to continiue")
)
( (not (Stuff to do #2))) ; evaluate arguments from user and continue if TRUE next to #3
(princ "\nStuff to do #2 are not done, do them to continiue")
)
( (not (Stuff to do #3))) ; evaluate arguments from user and continue if TRUE next for the code to compute
(princ "\nStuff to do #3 are not done, do them to continiue")
)
( (not (We got everything we need from Stuff #1, #2 and #3, now the code does its job... )) ; every argument has been evaluated, the code proceeds with the results
(princ "\nEverything is provided for the code, but it failed!")
)
);cond
以下是固定代码(这是一种做法):
; Moves selection from its center to the midpoint of the picked LINE or PLINE's segment
(defun c:test ( / pdm ss ssbox censsbox ent entitytype line endpt1 endpt2 midpt )
(vl-load-com)
(setq pdm (getvar 'PDMODE))
(setvar 'PDMODE 35)
(while
(cond
( (not (and (princ "\nSelect objects to move") (setq ss (ssget "_:L"))))
(princ "\nNothing selected.")
)
( (not (setq ssbox (LM:ssboundingbox ss)))
(princ "\nUnable to calculate bounding box for selection.")
)
( (not (setq censsbox (apply 'mapcar (cons '(lambda ( a b ) (/ (+ a b) 2.0)) ssbox)) ))
(princ "\nUnable to find bounding box's centroid.")
)
( (not (while (not (setq ent (entsel "\nPick a line or a polyline's segment"))) ent (princ "\nMissed.. Try again!")) )
)
( (not (setq entitytype (cdr (assoc 0 (entget (car ent))))) )
(princ "\nEntitytype not found.")
)
(
(not
(progn
(setq line (get_ends ent))
(setq endpt1 (carline))
(setq endpt2 (cadrline))
(setq midpt (mid endpt1 endpt2))
)
)
(princ "\nMidpoint of the line not found.")
)
(
(progn
(vl-cmdf "_.move" ss ""
"_non" censsbox
"_non" midpt
)
(princ (strcat "\nThis time you picked \"" entitytype "\" entity! " ))
)
)
);cond
(setvar 'PDMODE pdm)
);while
(princ)
)
; (command "_.POINT" endpt1 )
; (command "_.POINT" endpt2 )
; (command "_.POINT" censsbox )
; (command "_.POINT" midpt )
(defun mid (p1 p2)
(mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2.0)) p1 p2)
)
; Stefan BMR
(defun get_ends (e / o p p1 p2 b)
(setq o(car e)
b(eq (cdr (assoc 0 (entget o))) "LWPOLYLINE")
p(vlax-curve-getparamatpoint
o
(vlax-curve-getclosestpointto o (trans (cadr e) 1 0))
)
p1 (if b
(fix p)
(vlax-curve-getstartparam o)
)
p2 (if b
(1+ p1)
(vlax-curve-getendparam o)
)
)
(if (> (- p2 p) (- p p1))
(list
(trans (vlax-curve-getpointatparam o p1) 0 1)
(trans (vlax-curve-getpointatparam o p2) 0 1)
)
(list
(trans (vlax-curve-getpointatparam o p2) 0 1)
(trans (vlax-curve-getpointatparam o p1) 0 1)
)
)
)
(defun LM:listmid ( lst )
((lambda ( n ) (mapcar '(lambda ( x ) (/ x n)) (apply 'mapcar (cons '+ lst)))) (length lst))
)
;; Selection Set Bounding Box-Lee Mac
;; Returns a list of the lower-left and upper-right WCS coordinates of a
;; rectangular frame bounding all objects in a supplied selection set.
;; s - Selection set for which to return bounding box
(defun LM:ssboundingbox ( s / a b i m n o )
(repeat (setq i (sslength s))
(if
(and
(setq o (vlax-ename->vla-object (ssname s (setq i (1- i)))))
(vlax-method-applicable-p o 'getboundingbox)
(not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list o 'a 'b))))
)
(setq m (cons (vlax-safearray->list a) m)
n (cons (vlax-safearray->list b) n)
)
)
)
(if (and m n)
(mapcar '(lambda ( a b ) (apply 'mapcar (cons a b))) '(min max) (list m n))
)
)
编辑:
做了一些实验来解决一些小问题,我再次更改了这一部分:
( (while (not (setq ent (entsel "\nPick a line or a polyline's segment"))) ent )
)
用cond的每个语句进行这样的实验非常方便,而不会让代码立即失败! 我更喜欢测试
(and (do step 1)
(do step 2)
(do step 3)
)
如果任何步骤未能返回非零值,则此操作将停止。我不喜欢在其他测试中创建包含的拾取集
(while (not ss)
(setq ss (ssget)))
如果您没有选择任何内容,为什么要运行该程序?否则你必须重新开始例行程序。我的0.02美元
-大卫 我同意,大卫
我只是想尝试一下,看看这种编写代码的方式有什么不同。。。
所以你说的是这样的:
(if
(and ; Evaluate arguments from user within the "and" function
(if
(not (Stuff to do #1 ))
(princ "\nTheres something wrong in #1 try again!")
(Stuff to do #1 )
)
(if
(not (Stuff to do #2 ))
(princ "\nTheres something wrong in #2 try again!")
(Stuff to do #2 )
)
(if
(not (Stuff to do #3 ))
(princ "\nTheres something wrong in #3 try again!")
(Stuff to do #3 )
)
); All arguments are evaluated, the code proceeds
(while somethingisdone ; example: a selection was made and the same must be copied or moved within the while loop
(progn
(while
(not (setq pickline (entsel "\nPick a line")))
pickline
(cond
( (= 7 (getvar 'errno))
(princ "\nYou must select a line.")
)
( (null pickline)
(princ "\nYou missed, try again.")
)
)
); to exit this loop and continue a line must be picked
(We got everything we need from Stuff #1, #2 and #3, now the code does its job... )
); the code did its job, exiting with my favourite ESC key, and don't forget the error handling if needed!
)
);if
我做了一个有点复杂的例子,我不确定and函数中的那些“断点”是否会起作用。
无论如何,我正在努力向论坛中最好的人学习——每次我觉得我在做80%的代码,剩下的20%我必须得到你们的帮助,因为无论我多么努力,我似乎都不可能找到错误。 这更多的是个人喜好。
我的碰巧是:
[列表]
[*](initget)->(get)所有用户输入
[*](ssget)带过滤器
[*]做你正在做的事情
[/列表]
至于错误检查和报告,发生的绝大多数错误
在开发过程中,要么破坏整个例程,要么做一些非常重要的事情
显然,这是不可能错过的。
对我来说,另一个优先事项是可读性。我有几十年的习惯。如果有必要的话
有一天编辑它们,它的格式我可以快速阅读和破译。
(and)测试允许您同时进行多个测试。
例如,ie:
编辑仅为c色的第nnn\u个数字属性
(defun c:ean (/ n et ns ss i en an ad x et nv c)
(initget 7)
(setq n (getint "\nATTRIBute Number To Edit:"))
(while (or (not c)
(> c 255))
(initget 4)
(setq c (getint "\nATTRIBute Color Number: ")))
(initget 1 "Replace Prefix Suffix")
(setq et (getkword "\nEdit Type - Replace Prefix Suffix: "))
(cond ((= et "Replace")
(setq ns (getstring t (strcat "\nString To Add As ATTRIBute " (itoa n) ": "))))
((= et "Prefix")
(setq ns (getstring t (strcat "\nPrefix To Add As ATTRIBute " (itoa n) ": "))))
((= et "Suffix")
(setq ns (getstring t (strcat "\nPrefix To Add As ATTRIBute " (itoa n) ": ")))))
(while (not ss)
(setq ss (ssget (list (cons 0 "INSERT")
(cons 66 1)))))
(setq i 0)
(while (setq en (ssname ss i))
(setq an (entnext en)
ad (entget an)
x 1)
(while (= "ATTRIB" (cdr (assoc 0 ad)))
(and (= x n)
(= c (cdr (assoc 62 ad)))
(setq nv (cond ((= et "Replace") ns)
((= et "Prefix")(strcat ns (cdr (assoc 1 ad))))
((= et "Suffix")(strcat (cdr (assoc 1 ad)) ns))))
(setq ad (subst (cons 1 nv) (assoc 1 ad) ad))
(entmod ad))
(setq x (1+ x)
an (entnext an)
ad (entget an)))
(entupd en)
(setq i (1+ i)))
(prin1))
没有“正确”的方法,只有有效或无效的方法。这就是
正确配置以处理AutoCAD环境(本地化变量,
重置系统变量)
HTH-David
-大卫 是的,我知道。但有时,如果错误不那么明显,则需要切换这些断点。
除非您是VLIDE用户,并且具有其调试功能的优势。
大卫,
我一直想知道如何实现这样的语法颜色可读性。
我已经搜索过了,但我在任何地方都找不到如何通过在语法上应用颜色来增加语法,就像在你的示例中一样。 我不使用vlide接口(它直到2000年才出现)
在旧版本中,如果*error*设置为零并且遇到错误,则整个例程将被回调
(defun c:test ()
(setq *error* nil)
(setq a
(setq b
(setq c
(setq d (/ 1.0 0)))))
)
返回
Command: test
error: divide by zero
(/ 1.0 0)
(SETQ D (/ 1.0 0))
(SETQ C (SETQ D (/ 1.0 0)))
(SETQ B (SETQ C (SETQ D (/ 1.0 0))))
(SETQ A (SETQ B (SETQ C (SETQ D (/ 1.0 0)))))
(C:TEST)
*Cancel*
vs 2000及以后:
Command: test
; error: divide by zero
这就是我从不接受新版本的主要原因之一。
至于着色,大多数原始autolisp括号检查器都是颜色匹配程序。他们是独立的。exe文件。
当Autodesk放弃Compuserve作为其官方论坛并开始自己的基于互联网的论坛时,它只使用html格式。一些独立团体也是如此。
我只是做了一个lisp例程,转换了。lsp文件。htm文件并添加了颜色匹配。使用CADtutor,在消息正文中使用bbc编码。所以我简单地将例程更改为以bbc代码格式输出。
http://www.bbcode.org/reference.php
我主要在这里使用它,因为我觉得它是一个更好的教学工具。我确实使用Ally 3.0程序进行生产工作,在开发例程时进行错误检查和分析。
-大卫
页:
[1]
2