明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1203|回复: 9

[源码] (VisualLISP版本)多段线增删顶点(支持弧段)

  [复制链接]
发表于 2025-8-13 11:43:53 | 显示全部楼层 |阅读模式
本帖最后由 gzxl 于 2025-8-16 15:15 编辑

好多年没写过 lisp,最近闲,重试写下lisp(照着 ObjectARX版 翻译)。可能代码有些繁琐。

(VisualLISP版本)多段线增删顶点(支持弧段)
   添加顶点方式选项: 拾取点 or 两节点间按指定距离
   添加顶点的多段线子段类型: 直线段 or 弧段 or 全部
   起止点宽度未做处理

*** 增加顶点是在封闭多边形不改变面积情况下而编写的,之外的情况难免存在 bug ***








本帖子中包含更多资源

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

x

评分

参与人数 2明经币 +2 金钱 +5 收起 理由
tigcat + 1 + 5 很给力!
Bao_lai + 1 很给力!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
回复

使用道具 举报

发表于 2025-8-13 13:44:57 | 显示全部楼层
已下载,抽空试一下
回复 支持 反对

使用道具 举报

发表于 2025-8-13 16:17:12 | 显示全部楼层
对楼主精通多种编写语言和研究精神表示钦佩。支持源码。不过此功能有个好用一点的代码,你可以参考一下。http://bbs.mjtd.com/thread-189001-1-1.html

点评

哦,原来论坛已有,没写之前也搜了下没注意。  发表于 2025-8-14 04:23
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-8-13 16:43:50 | 显示全部楼层
本帖最后由 gzxl 于 2025-8-14 04:16 编辑

哦,原来论坛已有,没写之前也搜了下没注意。
回复 支持 反对

使用道具 举报

发表于 2025-8-13 17:06:48 | 显示全部楼层
这个功能现在CAD好像自带了

点评

我比较少用了,只是最近有人问我有没有插件  发表于 2025-8-14 04:21
回复 支持 反对

使用道具 举报

发表于 2025-8-14 12:54:35 | 显示全部楼层
gzxl 发表于 2025-8-13 16:43
哦,原来论坛已有,没写之前也搜了下没注意。

管它有没有,我也把这两天折腾的贴出来
  1. (vl-load-com)
  2. (defun bulgecentre(p1 p2 b);;计算弧段(子段凸度值非0)圆心,这个函数是抄的
  3.   (polar p1(+ (angle p1 p2) (-(/ pi 2)(* 2 (atAn b))))(/ (*(distance p1 p2) (1+ (* b b))) 4 b))
  4.   )
  5. (defun cenab2bulg(cen a b / l s);;根据弧段圆心及起止点计算凸度值
  6.   (setq s(if(MINUSP(car(trans(mapcar'- a cen)0(mapcar'- a b))))-1 1))
  7.   (setq l(trans(mapcar'- cen b)0(mapcar'- cen a))
  8.   l(*(angle'(0 0)(list(last l)(car l)))0.25)
  9.   l(if(MINUSP s)(-(* 0.5 pi)l)l))
  10.   (/(sin l)(cos l)s))
  11. (defun curvelengthof(e a b);;曲线e上两点间曲线距离(对于跨越闭合多段线起点的情况不适合,不过对本程序不影响,未进一步完善)
  12.   (-(vlax-curve-getdistatparam e(min(vlax-curve-getendparam e)b))(vlax-curve-getdistatparam e(max(vlax-curve-getstartparam e)a))))
  13. (defun partof(e p / i n closed a b);;返回多段线e指定点所在子段详细情况(起点宽度 止点宽度 凸度(起点param 起点坐标)(p点param p)(止点param 止点坐标)
  14.   (or(=(type e)'vla-object)(setq e(vlax-ename->vla-object e)))
  15.   (setq i(vlax-curve-getparamatpoint e(vlax-curve-getclosestpointto e p))
  16.   n(1-(vlax-curve-getendparam e))closed(vlax-get-property e 'closed))
  17.   (vlax-invoke-method e 'GetWidth(fix i)'a 'b)
  18.   (vl-list* a b(vlax-invoke-method e 'GetBulge(fix i))
  19.       (mapcar(function(lambda(x / p)
  20.             (if(setq p(vlax-curve-getPointAtParam e x))(List x p))))(List(fix i)i(1+(fix i))))))
  21. (defun delver(e i / arr arr1 i n i1 i2 n1 n2);|;;lw线上删点,处理凸度、起止宽度(本来想法是可以支持各种多段线的,但根据测试,通过PE命令曲线化得到的
  22. 二维多段线,无法获取、设置起止宽度getwidth、setwidth失效,vlax-invoke-method调用出错,vlax-invoke调用无反应),最终放弃了二维/三维多段线的处理|;
  23.   (and(or(=(type e)'vla-object)(setq e(vlax-ename->vla-object e)))
  24.       (=(vlax-get-property e'objectname)"AcDbPolyline")
  25.       (progn
  26.   (setq arr(vlax-safearray->list(vlax-variant-value(vlax-get-property e 'Coordinates)))
  27.         l(1-(/(length arr)2))
  28.         arr1(vlax-make-safearray 5(cons 0(+ l l -1)))
  29.         i1 -1 i2 -1 n1(+ i i)n2(1+ n1))
  30.   (vl-every(function(lambda(x)
  31.           (if(<= n1(setq i1(1+ i1)i2(1+ i2))n2)
  32.             (setq i1(1- i1))
  33.             (vlax-safearray-put-element arr1 i1 x))))arr)
  34.   (setq n1 i)
  35.   (if(< 0 i l)
  36.     (progn(or(zerop(setq b1(vlax-invoke-method e'getbulge(1- i))))
  37.        (zerop(setq b2(vlax-invoke-method e'getbulge i)))
  38.        (not(equal(setq cen(bulgecentre(vlax-curve-getpointatparam e(1- i))(vlax-curve-getpointatparam e i)b1))
  39.            (bulgecentre(vlax-curve-getpointatparam e i)(vlax-curve-getpointatparam e(1+ i))b2)1e-8))
  40.        (vlax-invoke-method e 'setbulge(1- i)(cenab2bulg cen(vlax-curve-getpointatparam e(1- i))(vlax-curve-getpointatparam e(1+ i)))))
  41.       (vlax-invoke-method e'getwidth(1- i)'i1 'i2)
  42.       (vlax-invoke-method e'getwidth i'i2 'i2)
  43.       (vlax-invoke-method e'setwidth(1- i)i1 i2)
  44.       t)t)
  45.   (while(< n1 l)(vlax-invoke-method e'setbulge n1(vlax-invoke-method e'getbulge(1+ n1)))(setq n1(1+ n1)))
  46.   (setq i(1+ i))
  47.   (while(<= i l)
  48.     (vlax-invoke-method e'getwidth i'i1 'i2)
  49.     (vlax-invoke-method e'setwidth(1- i)i1 i2)
  50.     (setq i(1+ i)))
  51.   (vlax-put-property e 'Coordinates arr1)))
  52.   )
  53. (defun mADDVERTEX(e p / i a n);;;加点,因为调用ADDVERTEX方法,它会自动处理后续点、子段的凸度及起止宽度,但对于所增加点需要根据情况重新计算该点前后两个子段的凸度及起止底宽
  54.   (setq a(partof e p)i(car(nth 4 a))n(if(> i 0)(1+(fix i))i))
  55.   (vlax-invoke e'ADDVERTEX n(2dp p))
  56.   (vl-every(function(lambda(x y)(set x(cadr y))))'(p1 p p2)(cdddr a))
  57.   (if(and(apply'and a)(< 0 i(1-(vlax-curve-getendparam e))))
  58.     (progn
  59.       (if(< 0(+(car a)(cadr a)))
  60.   (progn(setq kd(+(car a)(*(/(-(cadr a)(car a))(curvelengthof e(car(nth 3 a))(car(last a))))(curvelengthof e(car(nth 3 a))(car(nth 4 a))))))
  61.     (vlax-invoke-method e 'setwidth(1- n)(car a)kd)
  62.     (vlax-invoke-method e 'setwidth n kd(cadr a))))
  63.       (or(zerop(caddr a))
  64.    (vl-some(function(lambda(a b)
  65.           (VL-CATCH-ALL-APPLY(function vlax-invoke-method)(list e'setbulge a b))))
  66.      (List(1- n)n)
  67.      (setq cen(bulgecentre p1 p2(caddr a))
  68.            bulg(list(cenab2bulg cen p1 p)(cenab2bulg cen p p2))))))))
  69. (defun 2dp(pt)(mapcar'+'(0 0)pt))
  70. (defun C:y(/ e p a q i);|;;mADDVERTEX和delVERTEX函数示例,完败CASS的加点命令Y,
  71. 其它处理方式需要自动解决,处理好数据后调用mADDVERTEX和delVERTEX,想要一次性批量处理一系列点,还需要改写这两个函数|;
  72.   (if(and(setq e(car(entsel"\n选择要多线段")))
  73.    (sssetfirst nil(ssadd e))
  74.    (setq e(vlax-ename->vla-object e))
  75.    (=(vlax-get-property e'objectname)"AcDbPolyline"))
  76.     (while(setq P(getpoint "\r指定删除点或新顶点: "))
  77.       (if(and(=(fix(setq P(trans P 1 0)q(vlax-curve-getclosestpointto e p)
  78.        a(vlax-curve-getparamatpoint e q)))a)
  79.        (equal(2DP p)(2DP q)1e-5)
  80.        (>(vlax-curve-getendparam e)1))
  81.   (delver e(vlax-curve-getParamAtPoint e p))
  82.   (mADDVERTEX e p))
  83.       (vlax-invoke-method e 'Update))
  84.     )
  85.   (sssetfirst nil))

本帖子中包含更多资源

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

x

评分

参与人数 2明经币 +2 金钱 +50 收起 理由
USER2128 + 1 很给力!
gzxl + 1 + 50 很给力!

查看全部评分

回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-8-14 13:39:15 | 显示全部楼层
llsheng_73 发表于 2025-8-14 12:54
管它有没有,我也把这两天折腾的贴出来

我折腾了三天以上,不记得几天了,三天是肯定的。
回复 支持 反对

使用道具 举报

发表于 2025-8-14 13:44:50 | 显示全部楼层
保持宽度不变的增点,我也折腾过,源码放在仓库里发霉了都,

评分

参与人数 1明经币 +1 金钱 +50 收起 理由
gzxl + 1 + 50 早知道就找您要

查看全部评分

回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-1-12 04:09 , Processed in 0.221713 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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