明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2382|回复: 16

[函数] lisp求某一直线与多段线的交点

[复制链接]
发表于 2016-4-27 21:01 | 显示全部楼层 |阅读模式
请问各位大神,可以用lisp求某一直线与多段线的交点吗
发表于 2022-12-22 10:59 | 显示全部楼层
本帖最后由 zml84 于 2022-12-22 11:01 编辑
  1. (vl-load-com)
  2. ;;;=================================================================*
  3. ;;;      通用函数                                                   *
  4. ;;;功能:求两个线条对象的交点                                       *
  5. ;;;      适用对象: Line、Circle、Arc、Ellipse、Polyline、           *
  6. ;;;      LWPolyline、3dPolyline、Spline                             *
  7. ;;;参数:OBJ1   ----对象1                                           *
  8. ;;;      OBJ2   ----对象2                                           *
  9. ;;;      Extend ----延伸选项                                        *
  10. ;;;                 0  acExtendNone                                 *
  11. ;;;                 1  acExtendThisEntity                           *
  12. ;;;                 2  acExtendOtherEntity                          *
  13. ;;;                 3  acExtendBoth                                 *
  14. ;;;      ZZZ    ----输出选项                                        *
  15. ;;;                 "NON" 舍去Z值,返回二维坐标                     *
  16. ;;;                 "=0"  Z值取0                                    *
  17. ;;;                 "F1"  取第一个对象上的点                        *
  18. ;;;                 "F2"  取第二个对象上的点                        *
  19. ;;;                 "MAX" 取Z值大者                                 *
  20. ;;;                 "MIN" 取Z值小者                                 *
  21. ;;;      Fuzz   ----允许偏差值                                      *
  22. ;;;返回:若成功,返回点位表;否则返回nil                            *
  23. ;;;日期:zml84 于2007-11-05                                         *
  24. ;;;                                                                 *
  25. (defun ZL-GETINTERS (OBJ1   OBJ2   EXTEND ZZZ   FUZZ  /      ENT1
  26.          ENT2   PT10   PT11    PT20   PT21  OBJ11  OBJ22
  27.          ARRAY  LST     LST_PT I   PT  PT1    PT2
  28.          Z1      Z2
  29.         )
  30.   ;;0、对参数的格式化处理
  31.   (if (and (= (type EXTEND) 'INT)
  32.      (<= 0 EXTEND 3)
  33.       )
  34.     ()
  35.     (setq EXTEND 0)
  36.   )
  37.   (setq ZZZ (strcase ZZZ))
  38.   ;;======================
  39.   ;;1、获取交点集合>>>>>>>
  40.   (if (and (= (vla-get-objectname OBJ1) "AcDbLine")
  41.      (= (vla-get-objectname OBJ2) "AcDbLine")
  42.       )
  43.     ;;对直线对象(line) 特别处理
  44.     (progn
  45.       (setq ENT1 (entget (vlax-vla-object->ename OBJ1))
  46.       ENT2 (entget (vlax-vla-object->ename OBJ2))
  47.       )
  48.       (setq PT10 (assoc 10 ENT1)
  49.       PT11 (assoc 11 ENT1)
  50.       PT20 (assoc 10 ENT2)
  51.       PT21 (assoc 11 ENT2)
  52.       )
  53.       ;;去除Z坐标
  54.       (setq PT10 (list (cadr PT10) (caddr PT10))
  55.       PT11 (list (cadr PT11) (caddr PT11))
  56.       PT20 (list (cadr PT20) (caddr PT20))
  57.       PT21 (list (cadr PT21) (caddr PT21))
  58.       )
  59.       (setq LST (inters PT10 PT11 PT20 PT21 nil));_该处有弊端,需改进
  60.       (if LST
  61.   (setq LST (append LST '(0)))
  62.       )
  63.     )
  64.     (progn
  65.       ;;=====================
  66.       ;;复制实体
  67.       (setq OBJ11 (vla-copy OBJ1)
  68.       OBJ22 (vla-copy OBJ2)
  69.       )
  70.       ;;向xy平面投影,将Z坐标改为0
  71.       (TOXY OBJ11)
  72.       (TOXY OBJ22)
  73.       ;;获取交点集合
  74.       (setq ARRAY (vla-intersectwith OBJ11 OBJ22 EXTEND))
  75.       ;;删除复制后的对象
  76.       (vla-delete OBJ11)
  77.       (vla-delete OBJ22)
  78.       ;;由数组转换为表
  79.       (if (and ARRAY
  80.          (> (vlax-safearray-get-u-bound
  81.         (vlax-variant-value ARRAY)
  82.         1
  83.       )
  84.       1
  85.          )
  86.     )
  87.   (progn
  88.     (setq  LST (vlax-safearray->list
  89.           (vlax-variant-value ARRAY)
  90.         )
  91.     )
  92.   )
  93.       )
  94.     )
  95.   )
  96.   ;;======================
  97.   ;;2、分析整理>>>>>>>
  98.   (setq LST_PT '())
  99.   (if LST
  100.     (progn
  101.       (setq I 0)
  102.       (repeat (/ (length LST) 3)
  103.   ;;2.1 获取当前点位
  104.   (setq PT (list (nth I LST)
  105.            (nth (+ 1 I) LST)
  106.            (nth (+ 2 I) LST)
  107.      )
  108.   )
  109.   ;;2.2 获取对象上对应点位
  110.   (setq PT1 (vlax-curve-getclosestpointtoprojection
  111.         OBJ1
  112.         PT
  113.         '(0 0 1)
  114.       )
  115.         PT2 (vlax-curve-getclosestpointtoprojection
  116.         OBJ2
  117.         PT
  118.         '(0 0 1)
  119.       )
  120.   )
  121.   (setq Z1 (caddr PT1)
  122.         Z2 (caddr PT2)
  123.   )

  124.   ;;2.3 效验偏差值
  125.   ;;就是说:过滤:参数中有偏差值选项,却不满足要求的点位
  126.   (if (and FUZZ
  127.      (or (= (type FUZZ) 'REAL)
  128.          (= (type FUZZ) 'INT)
  129.      )
  130.      (not (equal Z1 Z2 FUZZ))
  131.       )
  132.     ;; 空处理
  133.     ()
  134.     ;;2.4 对输出选项的处理
  135.     (progn
  136.       (cond
  137.         ((= ZZZ "NON")
  138.          (setq PT (list (car PT1) (cadr PT1)))
  139.         )
  140.         ((= ZZZ "F1")
  141.          (setq PT PT1)
  142.         )
  143.         ((= ZZZ "F2")
  144.          (setq PT PT2)
  145.         )
  146.         ((= ZZZ "MAX")
  147.          (if (> Z1 Z2)
  148.      (setq PT PT1)
  149.      (setq PT PT2)
  150.          )
  151.         )
  152.         ((= ZZZ "MIN")
  153.          (if (< Z1 Z2)
  154.      (setq PT PT1)
  155.      (setq PT PT2)
  156.          )
  157.         )
  158.         (t
  159.          (setq PT PT)
  160.         )
  161.       ) ;_结束cond
  162.       (if  (member PT LST_PT)
  163.         ()
  164.         (setq LST_PT (cons PT LST_PT))
  165.       )
  166.     ) ;_结束progn
  167.   ) ;_结束if
  168.   (setq I (+ I 3))
  169.       ) ;_结束repeat
  170.     ) ;_结束progn
  171.   ) ;_结束if
  172.   ;;3、返回结果>>>>>
  173.   LST_PT
  174. ) ;_结束defun
  175. ;;;=================================================================*
  176. ;;;功能:曲线实体上每个控制点的z坐标值置为0.0                       *
  177. (defun TOXY (OBJ / NAME PT1 TP2 i)
  178.   ;;取得实体的类型名称
  179.   (setq NAME (vla-get-objectname OBJ))
  180.   (cond
  181.     ;;类型1
  182.     ;;直线(line)
  183.     ((= NAME "AcDbLine")
  184.      ;;取得直线的起终点坐标
  185.      (setq PT1 (vlax-variant-value (vla-get-startpoint OBJ))
  186.      PT2 (vlax-variant-value (vla-get-endpoint OBJ))
  187.      )
  188.      ;;改变z值为0.0
  189.      (vlax-safearray-put-element PT1 2 0.0)
  190.      (vlax-safearray-put-element PT2 2 0.0)
  191.      (vla-put-startpoint OBJ PT1)
  192.      (vla-put-endpoint OBJ PT2)
  193.     )
  194.     ;;类型2
  195.     ;;圆(circle)
  196.     ;;圆弧(arc)
  197.     ;;椭圆及椭圆弧(ellipse)
  198.     ((or (= NAME "AcDbCircle")
  199.    (= NAME "AcDbArc")
  200.    (= NAME "AcDbEllipse")
  201.      )
  202.      ;;取得中心点座标
  203.      (setq PT1 (vlax-variant-value (vla-get-center OBJ)))
  204.      ;;改变中心点座标z值为0.0
  205.      (vlax-safearray-put-element PT1 2 0.0)
  206.      (vla-put-center OBJ PT1)
  207.     )
  208.     ;;类型3
  209.     ;;多段线(polyline、lwpolyline)
  210.     ;;拟合的2维多段线(polyline、lwpolyline)
  211.     ((or (= NAME "AcDbPolyline")
  212.    (= NAME "AcDb2dPolyline")
  213.      )
  214.      ;;改变标高值为0.0
  215.      (vla-put-elevation OBJ 0.0)
  216.     )
  217.     ;;类型4
  218.     ;;三维多段线(3dpolyline)  
  219.     ((= NAME "AcDb3dPolyline")
  220.      ;;取得3维多段线的控制点
  221.      (setq PT1 (vlax-variant-value (vla-get-coordinates OBJ))
  222.      I   0
  223.      )
  224.      (repeat (/ (length (vlax-safearray->list PT1)) 3)
  225.        (vlax-safearray-put-element PT1 (+ I 2) 0.0)
  226.        (setq I (+ I 3))
  227.      )
  228.      (vla-put-coordinates OBJ PT1)
  229.     )
  230.     ;;类型5
  231.     ;;样条曲线(Spline)
  232.     ((= NAME "AcDbSpline")
  233.      ;;取得样条曲线的拟合点
  234.      ;;改变每个拟合点的z值为0.0
  235.      (setq PT1 (vlax-variant-value (vla-get-fitpoints OBJ))
  236.      I   0
  237.      )
  238.      (repeat (vla-get-numberoffitpoints OBJ)
  239.        (vlax-safearray-put-element PT1 (+ I 2) 0.0)
  240.        (setq I (+ I 3))
  241.      )
  242.      (vla-put-fitpoints OBJ PT1)
  243.      ;;取得样条曲线的控制点
  244.      ;;改变每个控制点的z值为0.0  
  245.      (setq
  246.        PT2 (vlax-variant-value (vla-get-controlpoints OBJ))
  247.        I   0
  248.      )
  249.      (repeat (vla-get-numberofcontrolpoints OBJ)
  250.        (vlax-safearray-put-element PT2 (+ I 2) 0.0)
  251.        (setq I (+ I 3))
  252.      )
  253.      (vla-put-controlpoints OBJ PT2)
  254.     )
  255.     (t NIL)
  256.   )
  257. ) ;_结束defun
  258. ;;;=================================================================*
  259. ;|;;
  260. (defun C:TTt (/ S1 S2 OBJ1 OBJ2)
  261.   (if (and (setq S1 (entsel "\n线1: "))
  262.      (setq S2 (entsel "\n线2: "))
  263.       )
  264.     (progn
  265.       (setq OBJ1 (vlax-ename->vla-object (car S1))
  266.       OBJ2 (vlax-ename->vla-object (car S2))
  267.       )
  268. (princ "\n0\t\t")
  269.       (princ (ZL-GETINTERS OBJ1 OBJ2 0 "Max" nil))
  270. (princ "\n1\t\t")
  271.       (princ (ZL-GETINTERS OBJ1 OBJ2 1 "Max" nil))
  272. (princ "\n2\t\t")
  273.       (princ (ZL-GETINTERS OBJ1 OBJ2 2 "Max" nil))
  274. (princ "\n3\t\t")
  275.       (princ (ZL-GETINTERS OBJ1 OBJ2 3 "Max" nil))
  276.     )
  277.   )
  278.   (princ)
  279. )
  280. ;;|;

发表于 2022-12-15 03:26 来自手机 | 显示全部楼层
tryhi 发表于 2016-4-28 13:14
是lisp

学习一下。。谢谢了
 楼主| 发表于 2016-4-27 21:08 | 显示全部楼层
跪求各位大神啊
发表于 2016-4-27 21:59 | 显示全部楼层
可以用vla-intersectwith
 楼主| 发表于 2016-4-27 22:34 | 显示全部楼层
tryhi 发表于 2016-4-27 21:59
可以用vla-intersectwith

十分感谢,我先查下用法
 楼主| 发表于 2016-4-27 23:45 | 显示全部楼层
tryhi 发表于 2016-4-27 21:59
可以用vla-intersectwith

您好,我查了下,您说的vla-intersectwith函数是VBA吗,这个我没用过,用lisp可以实现这个功能吗
 楼主| 发表于 2016-4-27 23:47 | 显示全部楼层
tryhi 发表于 2016-4-27 21:59
可以用vla-intersectwith

您好,我查了下,您说的vla-intersectwith函数是VBA吗,这个我没用过,用lisp可以实现这个功能吗
发表于 2016-4-28 09:49 | 显示全部楼层
窗外流逝的时光 发表于 2016-4-27 23:47
您好,我查了下,您说的vla-intersectwith函数是VBA吗,这个我没用过,用lisp可以实现这个功能吗

你不想用vlisp,非要用lisp,就用(inters pt1 pt2 pt3 pt4 [onseg])
pt1 pt2是直线的两个端点;
提取出多段线的全部顶点,相邻两个为pt3、pt4;
发表于 2016-4-28 13:14 | 显示全部楼层
窗外流逝的时光 发表于 2016-4-27 23:47
您好,我查了下,您说的vla-intersectwith函数是VBA吗,这个我没用过,用lisp可以实现这个功能吗

是lisp
  1. (defun try-lst-div (lst nn / lst2)
  2.   (foreach n lst
  3.     (if (and lst2 (/= nn (length (car lst2))))
  4.       (setq lst2 (cons (append (car lst2) (list n)) (cdr lst2)))
  5.       (setq lst2 (cons (list n) lst2))
  6.     )
  7.   )
  8.   (reverse lst2)
  9. )
  10. (defun try-inters-en(en1 en2 / nn pp)
  11.         (if(or(null en1)(null en2)(equal en1 en2))nil
  12.                 (progn
  13.                         (setq pp (vla-intersectwith
  14.                                                                  (vlax-ename->vla-object en1)
  15.                                                                  (vlax-ename->vla-object en2)
  16.                                                                  acExtendnone
  17.                                                          )
  18.                         )
  19.                         (setq nn (vlax-variant-value pp))
  20.                         (if(/= -1(VLAX-SAFEARRAY-GET-U-BOUND nn 1))
  21.                                 (try-lst-div (vlax-safearray->list (vlax-variant-value pp))3)
  22.                                
  23.                         )
  24.                 ))
  25. )
 楼主| 发表于 2016-4-28 18:34 | 显示全部楼层
819534890 发表于 2016-4-28 09:49
你不想用vlisp,非要用lisp,就用(inters pt1 pt2 pt3 pt4 [onseg])
pt1 pt2是直线的两个端点;
提取出 ...

您好,不是我非要用lisp,是我现在刚刚学习cad,现在也只会一点点lisp
 楼主| 发表于 2016-4-28 20:18 | 显示全部楼层
tryhi 发表于 2016-4-28 13:14
是lisp

您好,非常感谢,我好好研究一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-19 06:54 , Processed in 0.223411 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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