明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4233|回复: 28

[源码] 纯LISP方法取得选择集中首尾相连的直线函数

  [复制链接]
发表于 2021-6-28 09:54:34 | 显示全部楼层 |阅读模式
前段时间编程遇到要将首尾相连的直线从选择集中挑选出来的功能。用region方法虽然能实现但是运行速度较慢,明经找的首尾相连函数又不怎么理想,只好自己动手了,没想到还挺复杂,循环套循环的绕的人头晕,现在好像调试通过了,纯lisp方法,运行速度还算比较快,发出来共享,给有需要的朋友。

;;; [函数]取得选择集中首尾相连的直线
;;; 函数(lineclose ss p ),ss为直线选择集,
;;; p为真时,返回封闭直线端点列表。
;;; p为假时,返回封闭直线图元名列表。
(defun lineclose (ss p / ent i loop lsar lst lst0 lst00 lst001 lst01 lst1 lstn name pd pt3 pt4 ptn ptsar)
  (setq lst '())
  (repeat (setq i (sslength ss))
    (setq name (ssname ss (setq i (1- i))) ent (entget name))
    (if (= (cdr (assoc 0 ent)) "LINE")
      (setq lst (cons (list name (cdr (assoc 10 ent)) (cdr (assoc 11 ent))) lst))))
  (setq lst0 '()lst01 '())
  (while (setq lsar (car lst))
    (setq lst (cdr lst) lst1 lst ptsar (cadr lsar) ptn (last lsar))
    (setq lst00 (list (last lsar)) lst001 (list (car lsar)) loop t)
    (while loop
      (setq pd nil)
      (repeat (setq i (length lst1))
        (setq lstn (nth (setq i (1- i))        lst1)  pt3 (cadr lstn)  pt4 (last lstn))
        (if (equal pt3 ptn 0.00001)
          (setq ptn pt4        lst00 (cons pt4 lst00)        lst001 (cons (car lstn) lst001)
                lst1 (vl-remove lstn lst1) pd t)
          (if (equal pt4 ptn 0.00001)
            (setq ptn pt3 lst00 (cons pt3 lst00) lst001 (cons (car lstn) lst001)
                  lst1 (vl-remove lstn lst1)  pd t )))
        (if (equal ptn ptsar 0.00001)
           (setq loop nil lst0 (cons lst00 lst0)  lst01 (cons lst001 lst01))))
      (if (= pd nil)(setq loop nil))))
  (if p lst0 lst01 )
)

;;; 示例1:首尾相连直线生成多段线
(defun c:test1 (/ lst lst1 pt ss x)
  (setq ss (ssget (list '(0 . "line"))))
  (setq lst (lineclose ss t))
  (foreach x lst
    (entmake (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length x)) '(70 . 1))
               (mapcar '(lambda (pt) (cons 10 pt)) x ))))
  (princ)
)

;;; 示例2:首尾相连直线亮显
(defun c:test2 (/ lst name ss x)
  (setq ss (ssget (list '(0 . "line"))))
  (setq lst (lineclose ss nil))
  (foreach x lst  (foreach name x (redraw name 3)))
  (princ)
)


评分

参与人数 3明经币 +3 金钱 +50 收起 理由
yjtdkj + 1 + 50 赞一个!
xj6019 + 1 很给力!
start4444 + 1 很给力!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2021-6-29 08:54:57 | 显示全部楼层
本帖最后由 panliang9 于 2021-10-25 10:39 编辑

很早以前论坛里有一个贴子   “LISP 聚合 10000 个实体6秒”

是 “Urings” 写的,后来这个贴子找不到了。

他的程序就能以飞快的速度把炸碎的对象线连接起来。据“urings”在贴子里说这是他耗尽心力搞出的好东西。

我们获得了一些图纸,但图纸里块全碎了,利用他的程序很快的就把密密麻麻的对象理顺了。还是非常有用的。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1明经币 +1 金钱 +50 收起 理由
yjtdkj + 1 + 50 赞一个!

查看全部评分

回复 支持 3 反对 0

使用道具 举报

发表于 2021-8-26 01:11:11 | 显示全部楼层
本帖最后由 urings 于 2021-8-26 06:57 编辑
panliang9 发表于 2021-6-29 08:54
很早以前论坛里有一个贴子   “LISP 聚合 10000 个实体6秒”

是 “Urings” 写的,后来这个贴子是被他删 ...

当时是论坛出故障了,论坛的硬盘出故障了,数据丢失



回复 支持 1 反对 0

使用道具 举报

发表于 2021-10-27 10:39:35 | 显示全部楼层
我也搞了一个,利用过某点选选择循环得到相连线的点
        (while (setq ent (car line_wall_list))
                (setq pt0 (w:get-dxf ent 10))
                (entdel ent)
                (setq pts (list pt0))
                (if (and pt0)
                        (vla-ZoomWindow (vlax-get-acad-object)
                                (vlax-3d-point (w:get-npt pt0 50000 50000 0))
                                (vlax-3d-point (w:get-npt pt0 -50000 -50000 0))
                        )
                )
                (while (and
                                                 (setq ss (ssget "C" pt0 pt0 (list (cons 0 "LINE")(cons 8 "砼墙"))))
                                                 (if (and ss)(setq lst (w:ss->lst ss)))
                                                 (setq ent1 (car lst))
                                                 (setq pt0_10 (w:get-dxf ent1 10))
                                                 (setq pt0_11 (w:get-dxf ent1 11))
                                                 (if  (equal pt0 pt0_10 1e-6) (setq pt0 pt0_11)(setq pt0 pt0_10))
                                         )
                        (setq pts (cons pt0 pts))
                        (setq line_wall_list (vl-remove ent1 line_wall_list))
                        (entdel ent1)
                )
                (setq wallent (w:mk-pline pts (list (cons 8 wall) (cons 62 256)(cons 70 1))))
                (w:vl-hatch wallent "ANSI31" 100 256 wall_hacth 0)
                (setq line_wall_list (cdr line_wall_list))
        )
发表于 2021-6-28 10:07:45 来自手机 | 显示全部楼层
感谢无私分享
发表于 2021-6-28 10:31:41 | 显示全部楼层
感谢大神的分享
发表于 2021-6-29 08:49:47 | 显示全部楼层
对多段线无效吗???
发表于 2021-6-29 09:23:53 | 显示全部楼层
好像只对直线有用,希望能更新为对多段线也有用
发表于 2021-6-29 21:15:33 | 显示全部楼层

感谢大神的分享
发表于 2021-7-2 09:37:02 | 显示全部楼层
LeeMAC不是有一个链选吗Chain Selection,首尾相连的都可以选中
发表于 2021-7-2 09:49:04 | 显示全部楼层
首尾相接其实比较容易,可能需要注意剔除下重叠的线。
其实做到这个程度,再把圆弧加上去就更完美了。
可以取代PE命令合成多段线。
然后再利用格林公式处理顺时针逆时针问题。

我有用VBA编写相关功能,PE实在是不好用。
发表于 2021-7-2 13:30:38 | 显示全部楼层
感谢大神共享!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-25 21:44 , Processed in 0.231048 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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