明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 13045|回复: 24

[源码] 转换多段线

  [复制链接]
发表于 2013-4-4 09:26:54 | 显示全部楼层 |阅读模式
200明经币
要求将封闭的无线宽的多段线转换成带线宽的多段线,如下图



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

最佳答案

查看完整内容

上面的也不行,还是这样好

点评

能不能发个程序给我啊,谢谢  发表于 2013-4-7 13:51
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2013-4-4 09:26:55 | 显示全部楼层
上面的也不行,还是这样好
  1. (defun PLConvert (PLEntName / PtsLst0 PtsLst1 MinLeng LinLeng PtsLst2 Pnt0 Pnt1 Pnt2 Pnt3 Pnt4 Pnt5)
  2.   ;;获取闭合多段线所有顶点的坐标
  3.   (setq        PtsLst0        (mapcar        'cdr
  4.                         (vl-remove-if
  5.                           '(lambda (x) (/= 10 (car x)))
  6.                           (entget PLEntName)
  7.                         )
  8.                 )
  9.         ;;将起点后置
  10.         PtsLst1        (append (cdr PtsLst0) (list (car PtsLst0)))
  11.         ;;初始化最小长度为闭合多段线的总长
  12.         MinLeng        (apply '+ (mapcar 'distance PtsLst1 PtsLst0))
  13.         ;;获取多段线每一段的点对表
  14.         PtsLst1        (mapcar 'list PtsLst0 PtsLst1)
  15.   )
  16.   ;;搜索最小长度的那一段
  17.   (foreach x PtsLst1
  18.     (if        (< (setq LinLeng (apply 'distance x)) MinLeng)
  19.       (setq MinLeng LinLeng
  20.             PtsLst2 x
  21.       )
  22.     )
  23.   )
  24.   ;;最小长度那一段的前一点
  25.   (setq        Pnt0        (car PtsLst2)
  26.         ;;最小长度那一段的后一点
  27.         Pnt1        (cadr PtsLst2)
  28.         ;;最小长度那一段的中点
  29.         Pnt2        (mapcar '* (mapcar '+ Pnt0 Pnt1) '(0.5 0.5 0.5))
  30.         PtsLst0        (append        (member Pnt0 PtsLst0)
  31.                         (reverse (cdr (member Pnt0 (reverse PtsLst0))))
  32.                 )
  33.         ;;循环后置,将Pnt0、Pnt1两点放在点表的后面
  34.         PtsLst0        (append (cddr PtsLst0) PtsLst2)
  35.         ;;初始化变量Pnt3
  36.         Pnt3        Pnt1
  37.         ;;初始化变量PtsLst1,这个变量按顺序保存将要绘制的多段线的所有点
  38.         PtsLst1        (list Pnt2)
  39.         ;;修复部分
  40.         Pnt4    (car PtsLst0)
  41.         Pnt5    (polar Pnt2 (angle Pnt3 Pnt4) (* MinLeng 0.25))
  42.         LinLeng nil
  43.   )
  44.   (if (and (setq LinLeng (bpoly Pnt5))
  45.            (equal (vlax-curve-getarea LinLeng)
  46.                   (vlax-curve-getarea PLEntName)
  47.                   0.00001
  48.            )
  49.       )
  50.     nil
  51.     (progn
  52.       (setq Pnt2    (polar Pnt2 (angle Pnt5 Pnt2) (* MinLeng 0.5))
  53.             PtsLst1 (cons Pnt2 PtsLst1)
  54.             Pnt2    (polar Pnt2 (angle Pnt0 Pnt1) MinLeng)
  55.             PtsLst1 (cons Pnt2 PtsLst1)
  56.             Pnt2    (polar Pnt2 (angle Pnt3 Pnt4) (* MinLeng 0.5))
  57.             PtsLst1 (cons Pnt2 PtsLst1)
  58.       )
  59.     )
  60.   )
  61.   (if LinLeng (entdel LinLeng))
  62.   ;;如果相对起点Pnt3是最小长度那一段的前一点,那么停止循环
  63.   (while (not (equal Pnt3 Pnt0))
  64.     ;;获取相对终点Pnt4
  65.     (setq Pnt4 (car PtsLst0)
  66.           ;;点Pnt5和点Pnt4一起使用,作为前进或后退的方向
  67.           Pnt5 (cadr PtsLst0)
  68.           ;;根据相对起点Pnt3和相对终点Pnt4的长度和方向移动点Pnt2
  69.           Pnt2 (polar Pnt2 (angle Pnt3 Pnt4) (distance Pnt3 Pnt4))
  70.     )
  71.     ;;如果移动后点Pnt2在原多段线上,那么先在Pnt3 Pnt4方向上后退半个最小长度,再在Pnt4 Pnt5方向上后退半个最小长度;
  72.     ;;相反地,点Pnt2不在原多段线上,那么先在Pnt3 Pnt4方向上前进半个最小长度,再在Pnt4 Pnt5方向上前进半个最小长度。
  73.     ;;这么做的目的是始终使点Pnt2和下一次循环的相对起点保持对齐,距离是半个最小长度,并把两次调整过的点存储到PtsLst1表中。
  74.     (if (vlax-curve-getParamAtPoint PLEntName Pnt2)
  75.       (setq Pnt2    (polar Pnt2 (angle Pnt4 Pnt3) (* MinLeng 0.5))
  76.             PtsLst1 (cons Pnt2 PtsLst1)
  77.             Pnt2    (polar Pnt2 (angle Pnt5 Pnt4) (* MinLeng 0.5))
  78.             PtsLst1 (cons Pnt2 PtsLst1)
  79.       )
  80.       (setq Pnt2    (polar Pnt2 (angle Pnt3 Pnt4) (* MinLeng 0.5))
  81.             PtsLst1 (cons Pnt2 PtsLst1)
  82.             Pnt2    (polar Pnt2 (angle Pnt4 Pnt5) (* MinLeng 0.5))
  83.             PtsLst1 (cons Pnt2 PtsLst1)
  84.       )
  85.     )
  86.     ;;设置下一次循环的相对起点为这次的相对终点
  87.     ;;并移除点表的第一项
  88.     (setq Pnt3          Pnt4
  89.           PtsLst0 (cdr PtsLst0)
  90.     )
  91.   )
  92.   (setq PtsLst1 (reverse PtsLst1)
  93.         ;;给顶点添加组码10
  94.         PtsLst1 (mapcar '(lambda (x) (cons 10 x)) PtsLst1)
  95.         ;;计算顶点的个数
  96.         PtsLst2 (length PtsLst1)
  97.         ;;添加多段线各段的起点宽度和终点宽度
  98.         PtsLst1 (mapcar '(lambda (x) (list (cons 40 MinLeng) (cons 41 MinLeng) x)) PtsLst1)
  99.         PtsLst1 (cddr (apply 'append PtsLst1))
  100.         )
  101.   ;;绘制多段线
  102.   (entmake
  103.     (append '((0 . "LWPOLYLINE") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (100 . "AcDbPolyline") (8 . "0") (62 . 6) (70 . 0))
  104.             (list (cons 90  PtsLst2))
  105.             PtsLst1
  106.     )
  107.   )
  108.   (princ)
  109. )

点评

辛苦了,因为我找到了更好的转换方法,所以分给你了!  发表于 2013-4-5 14:10
回复

使用道具 举报

发表于 2013-4-4 10:01:16 | 显示全部楼层
本帖最后由 zzc83 于 2013-4-4 10:04 编辑

这个思路怎么和我的那么像。。。
只会简单的CAD操作
1 分解,
2删除小线条,
3生成中心线
4中心线加粗

点评

呵呵,不好弄才悬赏  发表于 2013-4-4 10:16

评分

参与人数 1明经币 +1 收起 理由
yjr111 + 1 谢谢关注

查看全部评分

回复

使用道具 举报

发表于 2013-4-4 10:59:57 | 显示全部楼层

点评

NO用  发表于 2013-4-4 11:13

评分

参与人数 1明经币 +1 收起 理由
yjr111 + 1 谢谢关注

查看全部评分

回复

使用道具 举报

发表于 2013-4-4 12:03:19 | 显示全部楼层
搞个框选填充,哈哈
回复

使用道具 举报

 楼主| 发表于 2013-4-4 16:42:43 | 显示全部楼层
初步方案,效果大致如此

本帖子中包含更多资源

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

x
回复

使用道具 举报

 楼主| 发表于 2013-4-4 18:40:24 | 显示全部楼层
真的有点难搞,现在上传一些难一点的典型形状

本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 2013-4-4 20:57:37 | 显示全部楼层
这样行不行?
寻找最长线段,其他线段都是垂直这跟线的。
回复

使用道具 举报

发表于 2013-4-4 21:11:42 | 显示全部楼层
以短线中心线向下延伸
回复

使用道具 举报

发表于 2013-4-4 21:45:28 | 显示全部楼层
批量填充就能搞定

点评

填充和多段线覆盖不一样  发表于 2013-4-4 22:34
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-1 09:16 , Processed in 0.201174 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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