明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 23549|回复: 91

如何在多点之间绘制最短的不交叉连线(附一个用于植物图块标注的程序源码)

    [复制链接]
发表于 2012-3-31 13:53:46 | 显示全部楼层 |阅读模式
本帖最后由 hb198075 于 2012-3-31 13:57 编辑

对选择的图块进行连线,要求获得最短的一种自身不交的连线方式。
已完成如下代码,感觉不理想,图块少时还不错,图块多了就乱了。望高手们赐教!
  1. ;;;测试程序
  2. (defun c:tt1 ( / e10 ent itm n na ptlst ss)
  3.   (if (setq ss (ssget '((0 . "INSERT"))))
  4.     (progn
  5.       (setq n 0)
  6.       (repeat (sslength ss)
  7. (setq na    (ssname ss n)
  8.        ent   (entget na)
  9.        e10   (cdr (assoc 10 ent))
  10.        ptlst (cons e10 ptlst)
  11.        n     (1+ n)
  12. )
  13.       )
  14.       (setq ptlst (bz-dianjuLst ptlst))
  15.       (command "_.PLINE")
  16.       (foreach itm ptlst
  17. (command itm)
  18.       )
  19.       (command "")
  20.     )
  21.   )
  22.   (princ)
  23. )
  24. ;;;获得最短的总点距
  25. (defun bz-dianjuLst (lst / a all b jd jl n pt tglst)
  26.   (setq n 0)
  27.   (while (< n (length lst))
  28.     (setq pt (nth n lst)
  29.    tglst (bz-getNextPoint pt lst)
  30.    jl (HB_GETdist tglst)
  31.    )
  32.     (setq jd(bz-getPlistInsert tglst)
  33.    jl(* jl jd)
  34.    );_根据交点数设置优先级,每多一个交点,则距加一倍
  35.     (setq all (cons (cons jl tglst) all)
  36.    n (1+ n)
  37.     )
  38.   )
  39.   (setq all(vl-sort all '(LAMBDA (a b)(< (car a)(car b)))))
  40.   (cdar all)
  41. )
  42. ;;;获得离当前点最近的下一点
  43. (defun bz-getNextPoint (pt lst / a b rel tmplst)
  44.   (setq tmplst lst)
  45.   (while tmplst
  46.     (setq tmplst (vl-sort tmplst
  47.      '(LAMBDA (a b) (< (DISTANCE pt a) (DISTANCE pt b)))
  48.    )
  49.    pt  (car tmplst)
  50.     )
  51.     (setq rel  (cons pt rel)
  52.    tmplst (cdr tmplst)
  53.     )
  54.   )
  55.   (REVERSE rel)
  56. )
  57. ;;;判断当前连线自身的交点数
  58. (defun bz-getPlistInsert (lst / jd len m n p1 p2 pt1 pt2 rel)
  59.   (setq n   0
  60. len (length lst)
  61. rel 1
  62.   )
  63.   (repeat (- len 2)
  64.     (setq p1 (nth n lst)
  65.    p2 (nth (1+ n) lst)
  66.    n  (1+ n)
  67.    m  (1+ n)
  68.     )
  69.     (repeat (- len n 2)
  70.       (setq pt1 (nth m lst)
  71.      pt2 (nth (1+ m) lst)
  72.      jd (INTERS p1 p2 pt1 pt2)
  73.      m (1+ m)
  74.       )
  75.       (if jd
  76. (setq rel (1+ rel))
  77.       )
  78.     )
  79.   )
  80.   rel
  81. )
  82. ;;;获得点连线的总长度
  83. (defun HB_GETdist (lst / rel n p1 p2 tmp)
  84.   (setq rel 0.0)
  85.   (if (> (length lst) 1)
  86.     (progn
  87.       (setq n 0)
  88.       (repeat (1- (length lst))
  89. (setq p1  (nth n lst)
  90.        p2  (nth (1+ n) lst)
  91.        n   (1+ n)
  92.        tmp (DISTANCE p1 p2)
  93.        rel (+ tmp rel)
  94. )
  95.       )
  96.     )
  97.   )
  98.   rel
  99. )

下面是测试图


本帖子中包含更多资源

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

x

点评

为什么看不到了?显示“提示: 作者被禁止或删除 内容自动屏蔽” 收录了就不给一部分看了吗?  发表于 2018-6-27 23:55
"觉得好,就打赏"
还没有人打赏,支持一下

本帖被以下淘专辑推荐:

 楼主| 发表于 2012-3-31 14:06:06 | 显示全部楼层
下面是自己使用多年的一个用于植物图块标注与统计的程序,先附图:

命令执行方式:ZW


本帖子中包含更多资源

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

x
回复 支持 2 反对 0

使用道具 举报

发表于 2014-8-11 09:05:27 | 显示全部楼层
学习了,谢谢分享.
回复 支持 0 反对 1

使用道具 举报

发表于 2018-6-27 23:53:20 | 显示全部楼层
为什么看不到了?显示“提示: 作者被禁止或删除 内容自动屏蔽”
回复 支持 0 反对 1

使用道具 举报

发表于 2018-2-9 10:20:18 | 显示全部楼层
感谢诸位高手分享程序!!!!
回复 支持 0 反对 1

使用道具 举报

发表于 2018-2-8 23:45:30 来自手机 | 显示全部楼层
谢谢楼主和各位高手,学习中
回复 支持 0 反对 1

使用道具 举报

发表于 2019-11-14 12:39:04 | 显示全部楼层
hb198075 发表于 2012-3-31 14:06
下面是自己使用多年的一个用于植物图块标注与统计的程序,先附图:

命令执行方式:ZW

楼主还在么?那个植物的lsp。好像还有个CAD样板文件吧.
回复 支持 0 反对 1

使用道具 举报

发表于 2012-6-27 08:43:16 来自手机 | 显示全部楼层
学习学习。
回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2012-4-2 09:08:48 | 显示全部楼层
Gu_xl 发表于 2012-4-1 23:33
发个动态串线程序:

看起来很好用的,速度应该比我那个快多了,不知道G版能不提供源码让我学习一下,我想加上自动计算最佳连线方式的功能,而不是由人来判断。
回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2019-11-26 11:14:59 | 显示全部楼层
这个是应用公司制图标准自动设置的标注,你手动建一个名称为“yD10"的标注样式就可以了。(后面的数字表示标注样式的比例)
回复 支持 1 反对 0

使用道具 举报

发表于 2012-3-31 14:10:19 | 显示全部楼层

点评

版主,你发的链接为什么唯独没有了6楼的?  发表于 2018-6-28 00:45
发表于 2012-3-31 14:12:38 | 显示全部楼层
hb198075 发表于 2012-3-31 14:06
下面是自己使用多年的一个用于植物图块标注与统计的程序,先附图:

命令执行方式:ZW

很多的个人函数哦,收下了
 楼主| 发表于 2012-3-31 14:18:03 | 显示全部楼层
感谢G版的热情,我先去看看~
 楼主| 发表于 2012-3-31 14:33:20 | 显示全部楼层
本帖最后由 hb198075 于 2012-3-31 14:34 编辑


G版你那个程序的思路比我灵活多了,不过也是在图块稍多些时连线就不大如意。只实现了不交叉,但没有实现最短连线,希望能有个更完美的算法了。

本帖子中包含更多资源

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

x
 楼主| 发表于 2012-4-1 17:34:52 | 显示全部楼层
本帖最后由 hb198075 于 2012-4-1 17:36 编辑

想了一天总算搞出来了,虽然法子比较笨,运算也有些慢,不过在处理100个图块以下时速度还是能忍受的,关键是连线比较完美的。先附个图

把源码也奉上,。。。循环用得比较多,速度有点慢,希望有朋友能帮着也优化一下~


  1. ;;;测试程序
  2. (defun c:tt1 ( / e10 ent itm n na ptlst ss oldvar)
  3.   (setq oldvar(getvar "OSMODE"))
  4.   (setvar "OSMODE" 0)
  5.   (if (setq ss (ssget '((0 . "INSERT"))))
  6.     (progn
  7.       (setq n 0)
  8.       (repeat (sslength ss)
  9. (setq na    (ssname ss n)
  10.        ent   (entget na)
  11.        e10   (cdr (assoc 10 ent))
  12.        ptlst (cons e10 ptlst)
  13.        n     (1+ n)
  14. )
  15.       )
  16.       (setq ptlst (bz-dianjuLst ptlst))
  17.       (command "_.PLINE")
  18.       (foreach itm ptlst
  19. (command itm)
  20.       )
  21.       (command "")
  22.     )
  23.   )
  24.   (setvar "OSMODE" oldvar)
  25.   (princ)
  26. )
  27. ;;;获得最短的总点距
  28. (defun bz-dianjuLst
  29.        (lst / a all b jd jl n n_sd newlst pt tglst)
  30.   (setq n 0
  31. n_sd 0
  32.   )
  33.   (while (< n (length lst))
  34.     (setq pt (nth n lst)
  35.    tglst (bz-getNextPoint pt lst)
  36.     )
  37.     (setq newlst (bz-getPlistInsert tglst)
  38.    tglst  (cadr newlst)
  39.    jl  (HB_GETdist tglst)
  40.     )
  41.     (setq all (cons (cons jl tglst) all)
  42.    n   (1+ n)
  43.     )
  44.   )
  45.   (setq all (vl-sort all '(LAMBDA (a b) (< (car a) (car b)))))
  46.   (cdar all)
  47. )
  48. ;;;获得离当前点最近的下一点
  49. (defun bz-getNextPoint (pt lst / a b rel tmplst)
  50.   (setq tmplst lst)
  51.   (while tmplst
  52.     (setq tmplst (vl-sort tmplst
  53.      '(LAMBDA (a b) (< (DISTANCE pt a) (DISTANCE pt b)))
  54.    )
  55.    pt  (car tmplst)
  56.     )
  57.     (setq rel  (cons pt rel)
  58.    tmplst (cdr tmplst)
  59.     )
  60.   )
  61.   (REVERSE rel)
  62. )
  63. ;;;判断当前连线自身的交点数
  64. (defun bz-getPlistInsert (lst / 1lst 2lst leftitm len mjd n num p1 p2 pt1 pt2 rellst)
  65.   (setq n      0
  66. len    (length lst)
  67. num    1
  68. rellst (list (car lst))
  69. 1lst   lst
  70.   )
  71.   (while (and (setq p1 (car 1lst))
  72.        (setq p2 (cadr 1lst))
  73.   )
  74.     (setq mjd  nil
  75.    1lst (cdr 1lst)
  76.    2lst (cdr 1lst)
  77.     )
  78.     (while (and (null mjd)
  79.   (setq pt1 (car 2lst))
  80.   (setq pt2 (cadr 2lst))
  81.   (setq 2lst (cdr 2lst))
  82.     )
  83.       (if (INTERS p1 p2 pt1 pt2)
  84. (setq mjd pt1)
  85.       )
  86.     )
  87.     (if mjd
  88.       (setq num  (1+ num)
  89.      leftitm (HB_LIST_LEFTITEM mjd 1lst)
  90.      1lst (cdr (member mjd 1lst))
  91.      1lst (append (list p1 mjd) (REVERSE leftitm) 1lst)
  92.       )
  93.       (setq rellst (cons p2 rellst))
  94.     )
  95.   )
  96.   (list num (REVERSE rellst))
  97. )
  98. ;;;获得点连线的总长度
  99. (defun HB_GETdist (lst / rel n p1 p2 tmp)
  100.   (setq rel 0.0)
  101.   (if (> (length lst) 1)
  102.     (progn
  103.       (setq n 0)
  104.       (repeat (1- (length lst))
  105. (setq p1  (nth n lst)
  106.        p2  (nth (1+ n) lst)
  107.        n   (1+ n)
  108.        tmp (DISTANCE p1 p2)
  109.        rel (+ tmp rel)
  110. )
  111.       )
  112.     )
  113.   )
  114.   rel
  115. )
  116. ;;;返回列表中某元素之前的列表
  117. (defun hb_list_leftItem (itm lst / tmplst rel)
  118.   (setq tmplst (REVERSE lst))
  119.   (while (setq tmplst (cdr (member itm tmplst)))
  120.     (setq rel tmplst)
  121.   )
  122.   (REVERSE rel)
  123. )


本帖子中包含更多资源

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

x

点评

这个很好但是不是相同的块名相连~------------------  发表于 2012-6-11 15:02

评分

参与人数 1明经币 +1 收起 理由
vectra + 1

查看全部评分

发表于 2012-4-1 23:33:42 | 显示全部楼层
本帖最后由 Gu_xl 于 2013-4-10 14:55 编辑

发个动态串线程序:


程序文件下载:
游客,本帖隐藏的内容需要发帖数高于 5 才可浏览,你当前发帖数只有 0

本帖子中包含更多资源

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

x

点评

这个很好但是不是相同的块名相连~  发表于 2012-6-11 14:57
发表于 2012-4-2 12:19:15 | 显示全部楼层
学习一下~~~~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-22 14:09 , Processed in 0.232648 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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