明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 940|回复: 18

[提问] 新人想不明白呀……怎么获得两点多段线的终点呢?

[复制链接]
发表于 2021-6-28 23:58 | 显示全部楼层 |阅读模式
工作繁忙,断断续续学了半个月,在大佬的帮助下会写点画双线的程序了,但是还停留在操作直线阶段,遇到多段线就整不明白了

我想知道怎么把多点多段线的各个点输出来,用car,cdr的组合命令获取他们,进行操作。但是我连两端点多段线都搞不懂
就比如这段代码
(defun c:tta (/ abc  start 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)

这是某次运行后输出的结果,可以看到把起点给我整出了两遍,无语了……
发表于 2021-6-29 10:13 | 显示全部楼层
送你几个提取数据的函数

;;返回包含每一出现在列表中的指定键的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 T  i 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))
                                )
                        )
                )
        )
)
 楼主| 发表于 2021-6-29 00:36 | 显示全部楼层
又仔细看了一下书,发现没有用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))
命令:

这又是为啥呢……
 楼主| 发表于 2021-7-11 23:09 | 显示全部楼层
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)))
  )

)
 楼主| 发表于 2021-6-29 00:05 | 显示全部楼层
有没有什么办法实时查看图元的组码呢?

我也是无语,假设abc是一条两个端点的多段线,
(assoc 10 abc)  得到的结果竟然是两遍起点么?

组码表里不是写着:
10
顶点坐标(在 OCS 中),多个条目;每个顶点一个条目

多段线有多个顶点时,assoc 10 不会把每个顶点都输出出来么?
发表于 2021-6-29 00:53 | 显示全部楼层
不能直接设abc,用entlast连接
(defun c:tta (/ abc  start 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)
)
 楼主| 发表于 2021-6-29 01:12 | 显示全部楼层
本帖最后由 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的话(我还没学到那呢……)

发表于 2021-6-29 08:44 | 显示全部楼层
2个端点的话,用reverse倒置就可以提取另一个端点,多个端点的话就要遍历提取了。entmakeX可以直接取得图元,不用ENTLAST也可以。
发表于 2021-6-29 10:09 | 显示全部楼层
多段线属于比较特殊的图元
不光是获取数据比较绕
生成和修改PL线也是比较麻烦
发表于 2021-6-29 12:47 | 显示全部楼层
在本论坛里搜索能解决你90%的疑问
发表于 2021-6-29 16:00 | 显示全部楼层
;纯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去除
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-6-29 07:45 , Processed in 0.171137 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表