列表中的3dpolyline
你好,世界!我正在制作一个程序来“收缩包装”用户选择的一组点。它要求2个种子点,并通过距离和角度的组合选择下一个种子点。我会在完成后发布,以防其他人发现它有用。
由于我对autolisp编码还不熟悉,所以我有一些小问题。
如何将数据输出为当前图层上的多段线?我现在已将其存储为列表。
命令:!点XYZ
((-48.5079 -0.709823 0.0) (-46.3576 4.23851 0.0) (-43.3432 14.1435 0.0)
(-38.6845 11.4073 0.0) (-48.5079 -0.709823 0.0))
我可以做entmake,但我该如何指定在当前层上进行呢?
此外,我还不得不将用户的点选择窗口过滤为仅点。
(设定值(ssget _W))
最后,有没有一种简洁的方法来比较检查一个点和另一个点的坐标是否相同?直接比较似乎不起作用,我假设它只比较坐标的引用。
非常感谢您的阅读和愉快的编码! 欢迎来到Cadtutor。
您可以创建entmake并包含代码以跟随层名称,例如(cons 8“YourLayerName”),或者将所需的层设置为当前层,这将
通常让entmake将实体放置在其上。
仅对点进行过滤;
(setq pts (ssget '((0 . "POINT"))))
当做
塔瓦特 太棒了,谢谢。我没想到,如果没有W,还会提示用户选择窗口。
我对entmake的实际工作原理感到非常困惑。为什么
工作,但是
不?
另一个令人困惑的地方仍然是,下面的返回为零
(设定点(ssget’((0.“点”)))
(=(entget(ssname点0))(entget(ssname点0)))
干杯
做记号 做这样的事情不是更容易吗
(setq x(长度ptsxyz))
(setq y 0)
(命令“pline”)
(重复x
(命令(第n个y ptsxyz))
(setq y(+y 1))
)
(命令“”) 这就是entmake的使用方式。。
(entmake
(list
(cons 0 "LINE")
(cons 10 '(0. 0. 0.))
(cons 11 '(1. 1. 0.))
)
)
对于你的第二个困惑,希望这就是你的意思。
(setq points (ssget '((0 . "POINT"))))
(= (cdr (assoc 0 (entget (ssname points 0)))) "POINT")
当做
这个麻烦制造者代码摘录有一些语法错误;请查找以下原始代码的修复程序:
(setq x '(10 0 0 0))
(entmake
(list
'(0 . "LINE")
x
'(11 1 1 0)
)
)
当做
米尔恰
查看用于比较搪瓷的(eq)函数
-大卫
你好,马克,
这并不是entmake函数行为的不同,而是提供给entmake的list参数是如何计算的。
这应该有助于您理解:
http://www.cadtutor.net/forum/showpost.php?p=258390&postcount=20
如果你还有问题,请提问。 这可能会有帮助。。。
(defun _pline (lst)
(if (and (> (length lst) 1)
(entmakex '((0 . "POLYLINE") (10 0. 0. 0.) (70 . ))
(foreach x lst (entmakex (list '(0 . "VERTEX") (cons 10 x) '(70 . 32))))
)
(cdr (assoc 330 (entget (entmakex '((0 . "SEQEND"))))))
)
) 你们太棒了!这位努力学习Autolisps的新手说,这很有帮助。
如果有人感兴趣,下面是我的代码,用于将选定的点连接到一个框中。它找到质心,然后根据上一个点和新点的质心之间的最小角度选择下一个点(使用需要法向量的cal ang)。所以所有的点都需要放置在三维平面上。
然后从创建的点列表中生成一条3dpolyline。
我可能会修改它,让用户选择几个“质心”,并比较上一个点和最近质心之间的角度,以找到下一个点。只是为了能够处理更尴尬的形状。
;Connects selected points into a box, finds next points by angle from last point to new
;point through centroid of all points. All points must lay on the same plane in 3d space.
;Mark Camball, March 2010
(defun c:p2b ();/ points length centroid p list_pt previousp i)
;;;;;;;;;;;;;;FIND CENTROID OF POINTS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun centroid(sspoints / sumx sumy sumz z)
(setq length (sslength points))
(setq sumx 0 sumy 0 sumz 0 z 0)
(repeat length
(setq sumx (+ sumx (car (cdr (assoc 10 (entget (ssname points z)))))))
(setq sumy (+ sumy (cadr (cdr (assoc 10 (entget (ssname points z)))))))
(setq sumz (+ sumz (caddr (cdr (assoc 10 (entget (ssname points z)))))))
(setq z (+ 1 z))
);_repeat
(setq sumx (/ sumx length) sumy (/ sumy length) sumz (/ sumz length) )
(list sumx sumy sumz)
);_centroid
;(setq sum '(0,0,0))? and add to list instead of 3 counters?
;;;;;;;;;;;;;;GET NORMAL VECTOR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun norm(sspoints / pt1 pt2 pt3)
(setq pt1 (cdr (assoc 10 (entget (ssname points 0)))))
(setq pt2 (cdr (assoc 10 (entget (ssname points 1)))))
(setq pt3 (cdr (assoc 10 (entget (ssname points 2)))))
(cal "nor(pt1,pt2,pt3)")
);_norm
;error if not all points on same plane or duplicate points chosen
;;;;;;;;;;;;DETERMINES THE NEXT POINT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun nextpoint( / amin n p2 acur pm)
(setq amin 500);loop makes this lower every time a lower value is found
(setq n 0)
(repeat length ;loop through all the points and save the next point to pm
;gets the coordinates from the nth point in selection set
(setq p2 (cdr (assoc 10 (entget (ssname points n)))))
;if the new point is not same as the last point made
(if (not (equal previousp p2))(progn
;set angle from lead point to centroid to point in question (3d angle needs normal vector p)
(setq acur (cal "ang(centroid,previousp,p2,p)"))
;if the angle is lowest found while looping through all points, make note (pm)
(if (< acur amin)(progn
(setq amin acur)
(setq pm p2)
))_if _progn
))_if _progn
(setq n (+ 1 n))
);_repeat
(setq pm pm);returns pm
);_nextpoint
;;;;;;;;;;;;;;;;;;PRINTS THE LIST AS A LINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun printlist(); / n p1)
;70.8 for 3d pline 66.1 for verticies follow
;70.32 ---- use 42.0 instead for pline
;sets 3dpolyline
;sets first point
;repeats the other poionts
;end polyline
(setq n 0)
(entmake (list (cons 0 "POLYLINE")(cons 66 1) (cons 70 ))
(setq p1 (nth n list_pt))
(entmake (list (cons 0 "VERTEX")(cons 10 p1)(cons 70 32)))
(repeat length
(setq p1 (nth (setq n (+ 1 n)) list_pt))
(entmake (list (cons 0 "VERTEX")(cons 10 p1)(cons 70 32)))
);_repeat
(entmake (list (cons 0 "SEQEND")))
(princ)
);_printlist
;;;;;;;;;START MAIN PROGRAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;load in the geometry calculator
(if (not c:cal)(arxload "geomcal"))
;sets world ucs
(command "ucs" "w")
;read in all point
(setq points (ssget '((0 . "POINT"))))
(setq length (sslength points))
;calculate centroif of points
(setq centroid (centroid points))
;calculate normal vector to points
(setq p (norm points)) ;(only uses 3 points and assumes all are in a plane)
;create a list to store points in order and sets first point
(setq list_pt (list (setq previousp (cdr (assoc 10 (entget (ssname points 0))))) ))
;each time through (once for every point after first) add one coord to end of list_pt
(setq i 1)
(while (< i length)
(setq list_pt (append list_pt (list (setq previousp (nextpoint)))))
(setq i (+ 1 i))
);_while
;add first point to end of list to close area
(setq list_pt (append list_pt (list (nth 0 list_pt)) ))
(printlist)
;(plines)
);_defun
页:
[1]
2