明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 209|回复: 2

[源码] 计算交叉连续多段的外轮廓

  [复制链接]
发表于 昨天 00:39 | 显示全部楼层 |阅读模式
本帖最后由 Sring65 于 2025-6-13 08:06 编辑


  1. (defun c:getOuterBoundary ()
  2.   (setq s (car (entsel)))
  3.   (setq pts (getPlinePts s))
  4.   (entmakeLWPOLYLINE (getOuterBoundary pts))
  5.   (princ)
  6. )
  7. (defun entmakeLWPOLYLINE (pts)
  8.   (entmake
  9.     (append
  10.       (list
  11.   '(0 . "LWPOLYLINE")
  12.   '(100 . "AcDbEntity")
  13.   '(100 . "AcDbPolyline")
  14.   '(62 . 1)
  15.   (cons 90 (length pts))    ; 点的数量
  16.           ; 闭合标志
  17.   (if (equal (caar pts) (car (last pts)) 1e-8)
  18.     (cons 70 1)
  19.     (cons 70 0)
  20.   )
  21.       )
  22.       (mapcar '(lambda (a) (cons 10 a)) pts)
  23.     )
  24.   )
  25. )
  26. (defun getPlinePts (ent)
  27.   (vl-remove-if
  28.     'null
  29.     (mapcar
  30.       '(lambda (x)
  31.    (if (= (car x) 10)
  32.      (cdr x)
  33.    )
  34.        )
  35.       (entget ent)
  36.     )
  37.   )
  38. )
  39. (defun getOuterBoundary  (pointList / pts ptxList ptmin tmp p0 p1)
  40.   (setq PIx2 (+ pi pi))
  41.   (setq tmp (mapcar '1- (apply 'mapcar (cons 'min pointList)))) ;最下点
  42.   (setq p0 (last (sortByDistance tmp pointList))) ;最下点近点
  43.   (setq pts (getNextIntsitepts tmp p0 pointList))
  44.   (setq tmp p0)
  45.   (while (and
  46.      (setq pts (getNextIntsitepts (car pts) (cadr pts) pointList))
  47.      (setq p0 (car pts))
  48.      (setq p1 (cadr pts))
  49.      (setq ptxList (cons p0 ptxList))
  50.      (not (equal p0 tmp 1e-6))  ;回到起点退出循环
  51.    )
  52.   )
  53.           ;补起点
  54.   (setq ptxList (cons tmp ptxList))
  55.   (if (not (equal (last ptxList) (car ptxList) 1e-6))
  56.     (setq ptxList (cons (last ptxList) ptxList))
  57.   )
  58.   ptxList
  59. )
  60. ;;;是否包含点
  61. (defun ContainsEqual (lst pts / i e return)
  62.   (setq i -1)
  63.   (while (setq e (nth (setq i (1+ i)) lst))
  64.     (if  (equal e pts 1e-6)
  65.       (setq return t
  66.       i     (length lst)
  67.       )
  68.     )
  69.   )
  70.   return
  71. )
  72. ;;;计算下一点位置
  73. (defun getNextIntsitepts
  74.        (p1 p2 pointList / lst ptx ptn minLen tmp y x ptxlst)
  75.   (setq  ptn    p2
  76.   minLen (1+ (distance p1 p2))
  77.   y      (last pointList)
  78.   )
  79.   (foreach x pointList
  80.     (if  (and (setq ptx (Inters p1 p2 x y))
  81.        (not (equal p1 ptx 1e-6))
  82.   )        ;计算交点
  83.       (progn
  84.   (setq tmp (Distance p1 ptx))
  85.   (if (equal tmp minLen 1e-6)
  86.     ;;防止交点重复
  87.     (setq  lst (cons x lst)
  88.     lst (cons y lst)
  89.     )
  90.     (if (< tmp minLen)
  91. ;;;取最近交点
  92.       (setq minLen tmp
  93.       ptn   ptx
  94.       lst   (list x y p2)
  95.       )
  96.     )
  97.   )
  98.       )
  99.       (if (checkOnline p1 p2 x y)  ;检查是否共线
  100.   (setq lst (cons x lst)
  101.         lst (cons y lst)
  102.   )
  103.       )
  104.     )
  105.     (setq y x)
  106.   )
  107.   (setq ptxlst (removeEqual ptn (removeEqual p1 lst)))
  108.   (cons ptn (sortByAngle p1 ptn (sortByDistance ptn ptxlst)))
  109.   ;;交点最小角度
  110. )
  111. (defun checkOnline (p1 p2 l1 l2 / ang)
  112.   (and
  113.     (or  (equal (setq ang (getangles p1 p2 l1)) PIx2 1e-8)
  114.   (equal ang pi 1e-8)
  115.     )
  116.     (or  (equal (setq ang (getangles p1 p2 l2)) PIx2 1e-8)
  117.   (equal ang pi 1e-8)
  118.     )
  119.   )
  120. )
  121. (defun sortByAngle (pt0 pt1 ptxlst / angb anga ang0)
  122.   (vl-sort ptxlst
  123.      '(lambda (a b)
  124.         (< (getAngles pt0 pt1 a) (getAngles pt0 pt1 b))
  125.       )
  126.   )
  127. )
  128. (defun sortByDistance (p ptxlst)
  129.   (vl-sort ptxlst
  130.      '(lambda (a b) (> (distance p a) (distance p b)))
  131.   )
  132. )
  133. (defun getAngles (pt1 pt2 pt3 / ang a1 a2)
  134.   (if (or (equals pt2 pt1 1e-6) (equals pt2 pt3 1e-6))
  135.     (+ pi pi)
  136.     (progn
  137.       (setq ang (- (Angle pt2 pt3) (Angle pt2 pt1)))
  138.       (if (< ang 0)
  139.   (setq ang (+ ang pi pi))
  140.       )
  141.       (if (equal ang 0 1e-6)
  142.   (+ pi pi)
  143.   ang
  144.       )
  145.     )
  146.   )
  147. )
  148. (defun equals (a b p)
  149.   (vl-every '(lambda (x y) (equal x y p)) a b)
  150. )
  151. (defun removeEqual (ptn ptxlst / lst)
  152.   (vl-remove-if
  153.     'null
  154.     (mapcar '(lambda (x)
  155.          (if (equal ptn x 1e-6)
  156.      nil
  157.      x
  158.          )
  159.        )
  160.       ptxlst
  161.     )
  162.   )
  163. )



本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 昨天 06:26 | 显示全部楼层
不封闭的多段线,按封闭计算,逻辑有问题。
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 07:41 来自手机 | 显示全部楼层
crtrccrt 发表于 2025-6-13 06:26
不封闭的多段线,按封闭计算,逻辑有问题。

对就是按封闭的算的
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-14 04:35 , Processed in 0.162374 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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