Utah_Indie 发表于 2022-7-6 10:00:49

正交多段线lisp。。。。一

我开始开发一个lisp,它将检查图形中的所有多段线的x或y坐标是否相等,并将每个不符合标准的多段线的颜色从“bylayer”更改为红色。
 
我在按顺序遍历每个对象以及当前对象中每个顶点的循环比较方面遇到了问题。
 
我要再次尝试的是检查建筑类型图形中的所有多段线是否为正方形,并提醒哪些不是正方形。
 
我不是Lisp程序的专家,请容忍我。如果你想很好地纠正我的语法,或者指导我犯了什么大错——甚至更好。
谢谢
Randy(第一个职位)
 
目前为止的代码:
 
(defun C:perp()
 
(defun A1()
 
(setq eFilter(列表(cons 0“多段线”));列表中的实体名称
(ssget“X”eFilter)
); 端部defun A1
(defun B1()
(setq eLen(长度eList));获取列表的长度
); 结束defun b1
(defun D1()
(setq Lwn 0);变量初始定义
(setq e 0);同上
(重复eLen;重复实体列表的长度)
(setq e1(car(n n e)))
(如果
(=e1 10)
(程序
(ERPI)
(普林斯(cdr(nth n e)))
); 关闭程序
 
); 如果关闭,则关闭
(setq Lwn(+1 Lwn))
(setq a(cdr(nth n e)))
); 关闭重复
); 关闭D1
(defun Esub()
(trace Esub)
(setq坐标(长度e1))
); 关闭Esub
(重复坐标;重复坐标列表的长度
(defun G1();将坐标解析为xa ya xb yb
(setq a(cdr(n次坐标e)))
(setq b(cdr(第n个(+coordLen 1)(+e 1)))
) ; G1端
;---------------开始子程序H1----------------------
(defun H1()
(setq xa(a车))
(setq ya(cadr a))
(setq xb(b车))
(setq yb(cadr b))
); 关闭H1
(defun H2()
(=0(-xa xb))
(=0(-ya-yb))
(T(命令“chprop”“p”“c”“red”“))
); 关闭h2
); 关闭重复
)

David Bethel 发表于 2022-7-6 10:10:51

你确定所有的实体都是旧式的重多边形,而不是LWpolyline吗?必须以两种不同的方式处理它们。此外,您还需要确定比较的容差。对于大多数此类计算,(=)过于严格-大卫

David Bethel 发表于 2022-7-6 10:22:14

如果您确定点被捕捉到相当高的公差,这可能是点列表的基本测试:
 

(setq pl '((0 1 0) (0 4 0) (0 6 0)))

(defun ortholst (pl / xvals yvals xeq yeq)
(setq xvals (mapcar 'car pl)
       yvals (mapcar 'cadr pl)
       xeq (apply '= xvals)
       yeq (apply '= yvals))
(or xeq yeq))

(prin1 (ortho_lst pl))

 
 
如果所有X或Y值都相等,则返回T-大卫

Utah_Indie 发表于 2022-7-6 10:34:57

谢谢大卫。它们确实需要捕捉,或者在导入到ESRI GIS平台时,将在任何空白区域创建一个小“地块”。我想我可能可以单独导航测试LWPolyline或POLYLINE对象。你知道我的循环在哪里崩溃了吗?我可能有30个左右的顶点来评估对象。此外,我可能需要为第一个测试复制第一个坐标,因为n+1=0是一个笨拙的第一个比较,如果这有任何意义的话。

David Bethel 发表于 2022-7-6 10:39:13

我想我明白你想做什么了。
 
这可能是一个起点:

(defun massoc (key alist / x nlist)
(foreach x alist
   (if (eq key (car x))
       (setq nlist (cons (cdr x) nlist))))
(reverse nlist))

(defun ortholst (pl / xvals yvals xeq yeq)
(setq xvals (mapcar 'car pl)
       yvals (mapcar 'cadr pl)
       xeq (apply '= xvals)
       yeq (apply '= yvals))
(or xeq yeq))

;(setq pl '((0 1 0) (0. 4 0) (0. 6 0)))

(and (setq i -1
         cs (ssadd)
         ss (ssget "X" '((0 . "LWPOLYLINE"))))
    (while (setq en (ssname ss (setq i (1+ i))))
         (setq ed (entget en)
               pl (massoc 10 ed))
         (cond ((ortholst pl))
               (T (ssadd en cs))))
    (if cs (command "_.CHPROP" cs "" "_C" 1 "")))

 
这同样适用于以3-4位小数精度创建的PLINE-大卫

Utah_Indie 发表于 2022-7-6 10:51:02

大卫,谢谢你。这看起来是一个很好的干净的解决方案。我希望我可以麻烦你一些额外的故障排除。我将您发布的最新代码粘贴到Visual Lisp控制台中,在当前图形中绘制了许多orhto和非正交闭合多段线,并运行了代码。无论正交或非正交状态如何,它都会将所有多段线变为红色。
 
我将代码的最后一节更改为(无效):
 
(如果是cs(命令“_.CHPROP”cs”“”\u C“2”)
(命令“_.CHPROP”cs”“\u C“1”)
 
接下来的几行是实验性的,看看我是否可以嵌入格式等,但我添加了一些问题;以注释语句的形式查看我是否理解这些步骤
 

(defun ortholst (pl / xvals yvals xeq yeq) ;defines the subroutine ortholst, defines variables pl and temporarily xvals yvals xeq and yeq
(setq xvals (mapcar 'car pl) ;sets the variable xvals as a real number extracted from the first entry of the list pl      yvals (mapcar 'cadr pl) ; sets the variable yvals as a real number extracted from the second entry of the list pl
       xeq (apply '= xvals)
       yeq (apply '= yvals)) ; tests xvals and yvals for any equivalency to the other ordered pairs, thus xeq and yeq become a T/F or 1/0 value?
(or xeq yeq)) ;if either the x or y coordinate is equal then true else false

;(setq pl '((0 1 0) (0. 4 0) (0. 6 0)))

(and (setq i -1;and, returns true if all conditions are true, else false, what are all the 'and' comparisons, and we are still under the 'or' xeq yeq comparison for true condition aren't we?
          cs (ssadd) ;not sure what cs is as a variable or first operator under the 'and' function
         ss (ssget "X" '((0 . "LWPOLYLINE")))) ;also not sure what the ss argument does
    (while (setq en (ssname ss (setq i (1+ i)))) ;looping through coordinate pairs?
         (setq ed (entget en)
               pl (massoc 10 ed)) ;runs the subroutine massoc for each of the number 'ed' coordinate pairs?
         (cond ((ortholst pl)) ;condition test of 'and' comparison?
               (T (ssadd en cs)))) ;not sure what the effect of this code is, explanation would help me
   (if cs (command "_.CHPROP" cs "" "_C" 1 ""))) ;I understand the basics of an if argument, but I am guessing that the syntax "(if cs (command..." means that "cs" is a test comparison? such as (setq cs(= 1 0))

我太感谢你了。你真是太客气了。
兰迪

David Bethel 发表于 2022-7-6 10:56:16

首先,感谢您对理解代码的兴趣和明显的努力!
 
对您的评论的一些评论:
 

; I added a command line call c:orth-lwp in the updated version

(defun ortholst (pl / xvals yvals xeq yeq) ;defines the subroutine ortholst,
   ; declares the aurgment pl
   ; defines variables xvals yvals xeq and yeq as local to this function only

(setq xvals (mapcar 'car pl) ; sets the variable xvals as a list of real numbers extracted from the first atom of the list pl
         yvals (mapcar 'cadr pl) ; sets the variable yvals as a list of real numbers extracted from the second atom of the list pl
       xeq (apply '= xvals)
       yeq (apply '= yvals))
; tests xvals and yvals atoms for all equivalency, thus xeq and yeq are bound to T / nil
; here is where the problem may be   The = call returns T ONLY if all of the atom are exactly equal.
; Point values are stored as REAL numbers and autocad uses 15 significant digits.
; If all of the the points are not exactly equal, then it will reurn nil
(or xeq yeq)) ;if either the x or y coordinates are equal then return T else nil

(and (setq i -1;and, evaluate all expressions until a nil return is encountered
; what are all the 'and' comparisons
; the color helps here. All of the magenta tests in the original ( blue in the updated ) post are evaluated
; the last call will return nil either way, but it dosen't matter as it is the last espression
, and we are still under the 'or' xeq yeq comparison for true condition aren't we? No
         cs (ssadd) ;create an empty PICKSET named cs ( ChangeSet )
         ss (ssget '((0 . "X" LWPOLYLINE")))) ; Create a PICKSET named ss of all LWPOLYLINEs in the drawing
    (while (setq en (ssname ss (setq i (1+ i)))) ;looping through a PICKESET
         (setq ed (entget en); Get the entity definition
               pl (massoc 10 ed)) ; extract all group 10 point values from the entity definition
         (cond ((ortholst pl)) ; Conditional test : If the subroutine othro_test returns T, Then do nothing
               (T (ssadd en cs)))) ; Elseif, then add the entity to the change set cs
    (if cs (command "_.CHPROP" cs "" "_C" 1 ""))) ; if the changes set is bound to a value, then issue the CHPROP command
; I changed this test to test if the length ofset is greater than 0 for clarity

 
更新的例程:
 
 

(defun c:orth-lwp (/ i cs ss en ed pl)

(defun massoc (key alist / nlist)
   (foreach x alist
   (if (eq key (car x))
         (setq nlist (cons (cdr x) nlist))))
   (reverse nlist))

(defun ortholst (pl / xvals yvals xeq yeq)
   (setq xvals (mapcar 'car pl)
         yvals (mapcar 'cadr pl)
         xeq (apply '= xvals)
         yeq (apply '= yvals))
   (or xeq yeq))

(and (setq i -1
         cs (ssadd)
         ss (ssget "X" '((0 . "LWPOLYLINE"))))
      (while (setq en (ssname ss (setq i (1+ i))))
             (setq ed (entget en)
                   pl (massoc 10 ed))
             (cond ((ortholst pl))
                   (T (ssadd en cs))))
      (if (> (sslength cs) 0)
          (command "_.CHPROP" cs "" "_C" 1 "")))

(prin1))

 
我的测试台dwg文件已附上。
 
我希望这有帮助。随时欢迎回到低谷-大卫
 
顺便说一句,你是在测试一个向量样条线,而不是一个矩形???主要区别:冲击:
 
PS PS看起来你精通一门计算机语言,顺便说一句,在Autolisp中,我们没有错。在大多数语言中,FALSE不是TRUE。我们有零,这是一个空列表。
所有这些都返回T:

(equal nil '())
(eq nil '())
(= nil '())
(not nil)
(null nil)
(listp nil)

测验图纸

David Bethel 发表于 2022-7-6 11:05:35

Randy,
 
在重读了第#6篇文章之后,我现在猜你实际上是在测试封闭的矩形形状。
 
要测试正交闭合多段线:
 
(defun c:orth lwr(/i cs ss en ed pl(defun massoc(key LIST/nlist)(foreach x LIST(if](eq键(汽车x(setq nlist(cons(cdr x)nlist反面列表(defun orthorct(pl/tmp tst(cons(last pl)pltst T(重复(length pl)(如果(不是(等于(rem color=PURPLE](角度(汽车tmp)(]cadr tmp(*pi 0.5]]0 1e-8](setq tst nil]](setq tmp(cdr tmp](和(setq i-1 cs(ssadd)ss(/colorssget“X”'((0。“LWPOLYLINE”(-4。”
页: [1]
查看完整版本: 正交多段线lisp。。。。一