新人想不明白呀……怎么获得两点多段线的终点呢?
工作繁忙,断断续续学了半个月,在大佬的帮助下会写点画双线的程序了,但是还停留在操作直线阶段,遇到多段线就整不明白了我想知道怎么把多点多段线的各个点输出来,用car,cdr的组合命令获取他们,进行操作。但是我连两端点多段线都搞不懂
就比如这段代码
(defun c:tta (/ abcstart edd )
(setq start (getpoint))
(setq edd (getpoint start))
(setq abc (entmake (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 2) (cons 10 start) (cons 10 edd))))
(princ (assoc 10 abc))
)
abc是两端点的直线,为什么结果只输出一个端点,输出两遍呢?我想知道另一个端点是啥,该怎么做呢?
命令: tta (10 121.633 110.994 0.0)(10 121.633 110.994 0.0)
这是某次运行后输出的结果,可以看到把起点给我整出了两遍,无语了……
送你几个提取数据的函数
;;返回包含每一出现在列表中的指定键的cdr(点对的后部分)的列表<适合处理pl线>
;;例 (massoc 40 (entget (car (entsel)))) 每个顶点的宽度
;;返回 (0.0 0.0 200.0 0.0)
(defun massoc( key alist / x nlist)
(if (= (type alist) 'ename)
(setq nlist (entget alist))
(setq nlist alist)
)
(mapcar 'cdr (vl-remove-if-not ''((x) (= (car x) key)) nlist))
)
;;145.1 [功能] 求多段线上每段的起、终点,以及可能的弧线段圆心。
;;运行结果示例
;|
( (p0 p1)
(p1 p2)
(p2 p3 cenpoa)
(p3 p4 cenpob)
(p4 p5)
)
|;
(defun getpldata( enttt / ) ;;c mc10 mc42 m pldata startpo endpo centpo td data
;;(setq ent (car (entsel)))
(setq ent enttt)
(setq c (entget ent))
(setq mc10 (massoc 10 c)) ;;各顶点坐标
(setq mc42 (massoc 42 c)) ;;各顶点凸度
;;(~~~ (length mc10))
;;(~~~ (length mc42))
(if (vlax-curve-isClosed ent)
(setq mc10 (append mc10 (list (car mc10)))
m (cdr (assoc 90 c))
)
(setq m (1- (cdr (assoc 90 c))))
)
(setq pldata '())
(repeat m
(setq startpo (car mc10)
mc10 (cdr mc10)
endpo (car mc10)
td (car mc42)
mc42 (cdr mc42)
)
(cond
( (= td 0)
(setq data (list startpo endpo))
)
( (> td 0)
(setq centpo
(mapcar '+
startpo
(vlax-curve-getsecondderiv ent (vlax-curve-getParamAtPoint ent startpo))
)
)
(setq data (list startpo endpo centpo))
)
( (< td 0)
(setq centpo
(mapcar '-
startpo
(vlax-curve-getsecondderiv ent (vlax-curve-getParamAtPoint ent startpo))
)
)
(setq data (list startpo endpo centpo))
)
)
(setq pldata (cons data pldata))
)
(reverse pldata)
)
;;145.2返回多段线上指定点所在分段的起、终点,以及可能的圆心坐标
(defun getplnbypo( ent po / pldata podist loop i vpo temp )
(setq pldata (getpldata ent))
(if (vlax-curve-isClosed ent)
(setq m (cdr (assoc 90 (entget ent))))
(setq m (1- (cdr (assoc 90 (entget ent)))))
)
(setq po (trans po 1 0)) ;;po必须转为WCS坐标
(setq po (vlax-curve-getClosestPointTo (*ent2obj* ent) po))
(setq podist (vlax-curve-getDistAtPoint (*ent2obj* ent) po))
(setq loop Ti 1)
(while loop
(if (= i m)
(setq loop NIL
temp (last pldata)
)
(progn
(setq vpo (car (nth i pldata)))
(if (>= (vlax-curve-getDistAtPoint ent vpo) podist)
(setq loop NIL
temp (nth (1- i) pldata)
)
(setq i (1+ i))
)
)
)
)
) 又仔细看了一下书,发现没有用entget
遂把代码改成这样
(defun c:ttb (/ abc start edd ell)
(setq start (getpoint))
(setq edd (getpoint start))
(setq abc (entmake (list '(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
'(100 . "AcDbPolyline")
(cons 90 2)
(cons 10 start)
(cons 10 edd)
)
)
)
(setq ell (entget abc))
(princ (assoc 10 ell))
(princ)
)
结果返回了一堆,
命令: TTB ; 错误: 参数类型错误: lentityp ((0 . "LWPOLYLINE") (100 . "AcDbEntity") (100 . "AcDbPolyline") (90 . 2) (10 4368.46 1568.42 0.0) (10 4837.59 2010.93 0.0))
命令:
这又是为啥呢…… wyl219 发表于 2021-7-3 13:04
因为是否打印存在于图层的信息表,而ssget筛选的是对象的信息表,所以应该是没办法直接利用.
我能想到的办 ...
大佬,再请教个问题呗,如果输UCS改了一下坐标,entmake创建的图元就跑偏了,就不是点哪画哪了,这种情况咋处理呢?
举个例子,以下是一个画双线的小lisp,我输ucs,然后随便点两个点,把鼠标指针的坐标改歪了,然后我发现,这个时候用这个小lisp画出来的双线是跑偏的,
如何规避这种情况呢?就是正常ucs也能指哪画哪,歪了的UCS也能指哪画哪
(defun c:hsxa (/ L1 L2 KU PT1 PT2 PT3 PT4 ZX ENT13 ENT24)
(setq L1 (getpoint))
(setq L2 (getpoint L1))
(setq KU (angle L1 L2))
(setq PT1 (polar L1 (+ KU (* 0.5 pi)) 100))
(setq PT2 (polar L1 (+ KU (* 1.5 pi)) 100))
(setq PT3 (polar L2 (+ KU (* 0.5 pi)) 100))
(setq PT4 (polar L2 (+ KU (* 1.5 pi)) 100))
(setq
ENT13 (entmakex (list '(0 . "LINE") (cons 10 pt1) (cons 11 pt3)))
)
(setq
ENT24 (entmakex (list '(0 . "LINE") (cons 10 pt2) (cons 11 pt4)))
)
) 有没有什么办法实时查看图元的组码呢?
我也是无语,假设abc是一条两个端点的多段线,
(assoc 10 abc)得到的结果竟然是两遍起点么?
组码表里不是写着:
10
顶点坐标(在 OCS 中),多个条目;每个顶点一个条目
多段线有多个顶点时,assoc 10 不会把每个顶点都输出出来么?
不能直接设abc,用entlast连接
(defun c:tta (/ abcstart edd )
(setq start (getpoint))
(setq edd (getpoint start))
(entmake (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 2) (cons 10 start) (cons 10 edd)))
(setq abc (entlast))
(princ (entget abc))
(princ)
) 本帖最后由 caocaosasd 于 2021-6-29 01:14 编辑
然后我打开了一个纯净的CAD,照着30集的那个lisp视频教程,一步一步操作如下
在命令行输入
命令: (setq e1 (entget(car(entsel))))
返回以下内容:
选择对象: ((-1 . <图元名: 7ff425c05d10>) (0 . "LWPOLYLINE") (330 . <图元名: 7ff425c039f0>) (5 . "249") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbPolyline") (90 . 2) (70 . 0) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 4012.48 1599.2) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (10 4124.66 1819.59) (40 . 0.0) (41 . 0.0) (42 . 0.0) (91 . 0) (210 0.0 0.0 1.0))
命令: (setq e2 (assoc 10 e1))
返回以下内容:
(10 4012.48 1599.2)
也就是说,assoc 10 对于多个端点的多段线,只会返回第一个点,不会返回所有点,这么坑爹呢……
所以请教大神们,如何操作能返回多段线的各个顶点呢?如果不用vlax的话(我还没学到那呢……)
2个端点的话,用reverse倒置就可以提取另一个端点,多个端点的话就要遍历提取了。entmakeX可以直接取得图元,不用ENTLAST也可以。 多段线属于比较特殊的图元
不光是获取数据比较绕
生成和修改PL线也是比较麻烦 在本论坛里搜索能解决你90%的疑问 ;纯lisp获取所有顶点
(setq ed(entget (setq en (car (entsel)))));获取关联表
(setq lst_tmp '()) ;初始化一个空表
(while (setq ed (member (assoc 10 ed ) ed)) ;找到下一个顶点,并把其后所有内容(包括这个顶点)重新赋值给ed,找不到时返回nil,结束循环
(setq lst_tmp (cons (car ed ) lst_tmp)) ;把关联表中第一个元素记录下来
(setq ed (cdr ed)) ;从ed中去除第一个元素,避免死循环
)
(print (reverse lst_tmp) );倒置列表并打印
(princ)
;纯lisp获取起点终点
(setq ed(entget (setq en (car (entsel)))));获取关联表
(setq start (assoc 10 ed)) ;获取第一个顶点
(setq end (assoc 10 (reverse ed)));倒置后获取第一个顶点,即原始的最后一个顶点
(print (list start end) );倒置列表并打印
(princ)
; 纯lisp获取到的点包含组码10,可用cdr去除
页:
[1]
2