kucha007 发表于 2023-4-14 23:26:56

【K:GetEntInters】计算直线和实体的交点

本帖最后由 kucha007 于 2023-4-15 09:53 编辑

单纯用ssget栏选配合ssnamex得到的交点在某些T形线或虚线间隙的位置会漏掉交点

(setq SS (ssget "F" (list p1 p2)'((0 . "*LINE,ARC,CIRCLE"))))
(apply 'append (mapcar '(lambda (x) (mapcar 'cadr (cdddr x))) (ssnamex SS)));交点坐标


http://bbs.mjtd.com/thread-109701-1-1.html
在论坛找到了黄大师的函数,加以改进如下:
;虚线间隙通过全局比例先放大再缩小得到交点。就是有点奇葩...感觉就像是栏选的一个bug一样?
;和栏选线重叠的端点,单独收集再合并到交点列表



;在直线的交点及重叠端点处画圆
(defun K:GetEntInters (/ DOC p1 p2 TmpEnt SS i en IntLst OnLinePts xx)
(vl-load-com)
(setq DOC (vla-get-ActiveDOCument (vlax-get-acad-object)))
(progn ;基础函数
    ;计算两实体的交点 by 自贡黄明儒
    (defun K:TwoEntInters (e1 e2 Flag / Lst NewLst)
      (setq Lst (vlax-invoke
                  (vlax-ename->vla-object e1)
                  'Intersectwith
                  (vlax-ename->vla-object e2)
                  Flag
                )
      )
      (while Lst
      (setq NewLst (cons (list (car Lst) (cadr Lst) (caddr Lst)) NewLst))
      (setq Lst (cdddr Lst))
      )
      NewLst
    )
    ;删除列表中重复的元素(容差) by Lee Mac
    (defun K:UniqueFuzz (Lst Fuzz)
      (if Lst
      (cons
          (car Lst)
          (K:UniqueFuzz
            (vl-remove-if
            (function (lambda (x) (equal x (car Lst) Fuzz)))
            (cdr Lst)
            )
            Fuzz
          )
      )
      )
    )
    ;收集在线段P1P2上的所有对象端点
    (defun K:PtOnLineLst (SS p1 p2 / pt Lst)
      (setq Lst '());清空列表
      (setq Lst '());清空列表
      (repeat (setq i (sslength SS))
      (setq en (ssname SS (setq i (1- i))))
      (setq Lst
          (append
            (list
            (vlax-curve-getstartpoint (vlax-ename->vla-object en))
            (vlax-curve-getendpoint (vlax-ename->vla-object en))
            )
            Lst
          )
      )
      );收集端点坐标
      (vl-remove-if-not
          '(lambda (pt) (equal (distance p1 p2) (+ (distance pt p1) (distance pt p2)) 0.001))
          Lst
      );过滤掉不在直线上的端点
    )
)
(graphscr);返回图形交互界面
(vla-startundomark DOC)
    (setq p1 (getpoint "\n→请输入栏选的第一点:"))
    (if (setq p2 (getpoint p1 "\n→请输入栏选的第二点:"))
      (progn
      (setvar "LTSCALE" (* (getvar "LTSCALE") 100));全局比例放大
      (command "regen");刷新视图
      
      (setq SS (ssget "F" (list p1 p2) '((0 . "*LINE,ARC,CIRCLE"))))
      (setq OnLinePts (K:PtOnLineLst SS p1 p2));重叠的端点
      
      (setq TmpEnt
          (entmakex
            (list
            (cons 0 "LINE")
            (cons 10 (trans p1 1 0))
            (cons 11 (trans p2 1 0))
            )
          )
      );创建临时直线
      (setq IntLst '());空表
      (repeat (setq i (sslength SS))
          (setq en (ssname SS (setq i (1- i))))
          (setq IntLst (append (K:TwoEntInters TmpEnt en 0) IntLst))
      );收集交点列表
      (entdel TmpEnt);删除临时直线
      
      (setvar "LTSCALE" (/ (getvar "LTSCALE") 100));全局比例缩小
      (command "regen");刷新视图
      
      (setq IntLst
          (vl-sort
            (K:UniqueFuzz (append OnLinePts IntLst) 0.01);;合并点表后去重
            '(lambda (x y) (< (distance (trans p1 1 0) x) (distance (trans p1 1 0) y))) ;距离越短的点排在前面
          );排序:离起点越近越排在前面
      )
      (foreach xx IntLst
          (entmake
            (list
            (cons 0 "CIRCLE")
            (cons 10 xx)
            (cons 40 2.0);半径2
            (cons 62 6);洋红色
            )
          )
      );绘制圆弧
      )
    )
(vla-endundomark DOC)
(princ)
)



hubeiwdlue 发表于 2024-4-11 16:21:15

谢谢苦茶大神的分享。
页: [1]
查看完整版本: 【K:GetEntInters】计算直线和实体的交点