明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3624|回复: 7

创建外轮廓线(非面域方式)

[复制链接]
发表于 2011-11-15 14:11:13 | 显示全部楼层 |阅读模式
本帖最后由 feng582304 于 2011-11-15 14:13 编辑

奋斗了一段时间,终于差不多完成了,自己做了简单测试,简单的图形好象还行,复杂一点的好象还是有点问题,大家帮忙看一下,谢谢!!!
  1. ;-------------------------------------------------------------------------------;
  2. ;    总执行函数              ;
  3. ;1.点最右下角的点选对象(feng-wlkx-pointtossget 点)        ;
  4. ;2.对选集进行逆时针判断(feng-wlkx-ssgettominangle 模型 选集 前个节点 当前节点)  ;
  5. ;3.通过对象选择选集(feng-wlkx-sstossget 基准对象 前一个节点 当前节点)    ;
  6. ;4.对选集进行交点计算(feng-wlkx-ssgettointer 指定对象 选集 当前节点)    ;
  7. ;5.重复步骤1.2.3.4,如果步骤3选集为0时,调整前一个节点,再次执行步骤2.3.4  ;
  8. ;6.当计算的交点与起始点重合时结束,列出((节点 对象)...)        ;
  9. ;7.创建外轮廓线(feng-wlkx-makeplinelist 模型 ((节点 对象)...))      ;
  10. ;-------------------------------------------------------------------------------;
  11. (defun c:asdf ( / ms p0 )
  12.   (setq ms (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))
  13.   p0 (getpoint)
  14.   )
  15.   (feng-wlkx-run ms p0 nil nil '())
  16.   )
  17. (defun feng-wlkx-run ( ms p0 p1 p2 pli / pointtossget sstossget ssgettointer s1 inp )
  18.   (if (and (null p1) (null p2))
  19.     (setq p2 p0
  20.     p1 (list (- (car p0) 2) (cadr p0) 0)
  21.     )
  22.     )
  23.   (setq pointtossget (FENG-WLKX-POINTTOSSGET p2))
  24.   (princ "\n-------pointtossget-------\n")
  25.   (princ pointtossget)(princ "--->>>")(princ (sslength pointtossget))
  26.   (princ "\n-------pointtossget-------\n")
  27.   (setq s1 (cadr (nth 0 (FENG-WLKX-SSGETTOMINANGLE ms pointtossget p1 p2))))
  28.   (setq sstossget (FENG-WLKX-SSTOSSGET s1 p1 p2))  
  29.   (while (= (sslength (car sstossget)) 0)
  30.     (setq s1 (cadr (nth 0 (FENG-WLKX-SSGETTOMINANGLE ms pointtossget (cadr sstossget) p2)))
  31.     sstossget (feng-wlkx-sstossget s1 (cadr sstossget) p2)
  32.     )
  33.     )
  34.   (princ "\n-----p2----s1-----\n")
  35.   (princ p2)(princ "--->>")(princ s1)
  36.   (princ "\n-----p2----s1-----\n")
  37.   (setq pli (append pli (list (list p2 s1)))
  38.   inp (car (nth 0 (FENG-WLKX-SSGETTOINTER s1 (car sstossget) p2)))
  39.   )
  40.   (princ "\n--------inp-------\n")
  41.   (princ inp)
  42.   (princ "\n--------inp-------\n")
  43.   (if (<= (DISTANCE p0 inp) 1e-5)
  44.     (feng-wlkx-makeplinelist ms pli)
  45.     (progn
  46.       (setq pointtossget nil
  47.       s1 nil
  48.       sstossget nil
  49.       )
  50.       (feng-wlkx-run ms p0 p2 inp pli)
  51.       )
  52.     )
  53.   )
  54. ;-------------------------------------------------------;
  55. ;  对块、多段线进行临时分解,返回临时对象列表  ;
  56. ;              ;
  57. ;  (feng-wlkx-ssget-explode 块或多段线)    ;
  58. ;              ;
  59. ;    返回列表(临时分解对象)      ;
  60. ;-------------------------------------------------------;
  61. ;-------------------------------------------------------;
  62. ;    选择块或多段线        ;
  63. ;-------------------------------------------------------;
  64. (defun feng-ssgettoexplode ( / ss li n na )
  65.   (setq ss (ssget '((0 . "*POLYLINE,INSERT")))
  66.   li '()
  67.   )
  68.   (if ss
  69.     (progn
  70.       (repeat (setq n (sslength ss))
  71.   (setq na (vlax-ename->vla-object (ssname ss (setq n (1- n))))
  72.         li (append li (feng-wlkx-ssget-explode na))
  73.         )
  74.   )
  75.       )
  76.     )
  77.   li
  78.   )
  79. ;-------------------------------------------------------;
  80. ;    对块或多段线进行临时分解    ;
  81. ;-------------------------------------------------------;
  82. (defun feng-wlkx-ssget-explode ( ss / li ex na )
  83.   (setq li (setq ex (vlax-safearray->list (vlax-variant-value (vla-Explode ss)))))
  84.   (MAPCAR '(LAMBDA (x)
  85.        (if (or (= (vla-get-ObjectName x) "AcDbPolyline") (= (vla-get-ObjectName x) "AcDbBlockReference"))
  86.          (setq li (append li (feng-wlkx-ssget-explode x))) (vla-update x))
  87.        )
  88.     ex
  89.     )
  90.   li
  91.   )
  92. ;-------------------------------------------------------;
  93. ;    对选集进行逆时针判断      ;
  94. ;              ;
  95. ;(feng-wlkx-ssgettominangle 模型 选集 前个节点 当前节点);
  96. ;              ;
  97. ;  返回排序后的(list (交点 对应的对象)...)    ;
  98. ;-------------------------------------------------------;
  99. (defun feng-wlkx-ssgettominangle ( ms ss p-1 p0 / s1 n nn cir inp li )
  100.   (setq cir (vla-AddCircle ms (vlax-3d-point p0) 2)
  101.   li '()
  102.   )
  103.   (repeat (setq n (sslength ss))
  104.     (setq s1 (vlax-ename->vla-object (ssname ss (setq n (1- n))))
  105.     inp (vlax-variant-value (vla-IntersectWith s1 cir acExtendNone))
  106.     )
  107.     (if (> (vlax-safearray-get-u-bound inp 1) 0)
  108.       (repeat (/ (setq nn (length (setq inp (vlax-safearray->list inp)))) 3)
  109.   (setq li (cons (list (list (nth (setq nn (- nn 3)) inp) (nth (+ nn 1) inp) (nth (+ nn 2) inp)) s1) li))
  110.   )
  111.       )
  112.     )
  113.   (vla-delete cir)
  114.   (setq li (vl-sort li '(LAMBDA (x y) (< (feng-3pointtoangle p-1 p0 (car x)) (feng-3pointtoangle p-1 p0 (car y))))))
  115. )
  116. ;-------------------------------------------------------;
  117. ;    选择通过点的对象      ;
  118. ;              ;
  119. ;  (feng-wlkx-pointtossget 点)      ;
  120. ;    返回选集        ;
  121. ;-------------------------------------------------------;
  122. (defun feng-wlkx-pointtossget ( p / li )
  123.   (setq li (list
  124.        (list (- (car p) 1) (- (cadr p) 1) 0)
  125.        (list (- (car p) 1) (+ (cadr p) 1) 0)
  126.        (list (+ (car p) 1) (+ (cadr p) 1) 0)
  127.        (list (+ (car p) 1) (- (cadr p) 1) 0)
  128.        )
  129.   )
  130.   (ssget "cp" li '((0 . "LINE,ARC,CIRCLE")))
  131.   )
  132. ;-------------------------------------------------------;
  133. ;    创建外轮廓线        ;
  134. ;              ;
  135. ;  (feng-wlkx-makeplinelist 模型 ((节点 对象)...))  ;
  136. ;              ;
  137. ;    返回列表        ;
  138. ;-------------------------------------------------------;
  139. (defun feng-wlkx-makeplinelist ( ms li / dt n dtli pli s1 p1 p2 sa )
  140.   (setq dtli '()
  141.   pli '()
  142.   n -1
  143.   li (feng-wlkx-makeplinelist-delete li)
  144.   li (REVERSE (cons (nth 0 li) (REVERSE li)))
  145.   )
  146.   (repeat (length li)
  147.     (setq p1 (car (nth (setq n (1+ n)) li))
  148.     s1 (cadr (nth n li))
  149.     )
  150.     (if (and (= (vla-get-ObjectName s1) "AcDbArc") (<= n (- (length li) 2)))
  151.       (setq p2 (car (nth (1+ n) li))
  152.       dtli (cons (list (feng-wlkx-arctocon s1 p1 p2) n) dtli)
  153.       )
  154.       )
  155.     (setq pli (append pli p1))
  156.     )
  157.   (setq s1 (vla-AddPolyline ms (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble (cons 0 (- (length pli) 1))) pli)))
  158.   (repeat (setq n (length dtli))
  159.     (vla-SetBulge s1 (cadr (nth (setq n (1- n)) dtli)) (car (nth n dtli)))
  160.     )
  161.   )
  162. (defun feng-wlkx-makeplinelist-delete ( li / n nn li1 li2 tt n1 n2 )
  163.   (setq li2 li
  164.   li1 '()
  165.   )
  166.   (while (/= li1 li2)
  167.     (setq n 0)
  168.     (while (<= n (- (length li2) 1))
  169.       (if (or (= n (- (length li2) 1)) (= n 0))
  170.   (setq li1 (append li1 (list (nth n li2)))
  171.         n (1+ n)
  172.         )
  173.   (if (> (DISTANCE (car (nth (1- n) li2)) (car (nth (1+ n) li2))) 1)
  174.     (setq li1 (append li1 (list (nth n li2)))
  175.     n (1+ n)
  176.     )
  177.     (setq n (+ n 2))
  178.     )
  179.   )
  180.       )
  181.     (repeat (setq n1 (length li1))
  182.       (setq n1 (1- n1))
  183.       (repeat (setq n2 n1)
  184.   (if (and (null tt) (<= (DISTANCE (car (nth n1 li1)) (car (nth (setq n2 (1- n2)) li1))) 1e-5))
  185.     (setq tt t)
  186.     )
  187.   )
  188.       )
  189.     (if tt
  190.       (setq li2 li1
  191.       li1 '()
  192.       tt nil
  193.       )
  194.       (setq li2 li1)
  195.       )
  196.     )
  197.   li1
  198.   )
  199. ;-------------------------------------------------------;
  200. ;    计算选集与指定对象的交点    ;
  201. ;              ;
  202. ;  (feng-wlkx-ssgettointer 指定对象 选集 当点前)  ;
  203. ;              ;
  204. ;    返回交点列表        ;
  205. ;-------------------------------------------------------;
  206. (defun feng-wlkx-ssgettointer ( s1 ss p / s2 n nn inp li )
  207.   (setq li '())
  208.   (repeat (setq n (sslength ss))
  209.     (setq s2 (vlax-ename->vla-object (ssname ss (setq n (1- n))))
  210.     inp (vlax-variant-value (vla-IntersectWith s1 s2 acExtendNone))
  211.     )
  212.     (if (> (vlax-safearray-get-u-bound inp 1) 0)
  213.       (repeat (/ (setq nn (length (setq inp (vlax-safearray->list inp)))) 3)
  214.   (setq li (cons (list (list (nth (setq nn (- nn 3)) inp) (nth (+ nn 1) inp) (nth (+ nn 2) inp)) s1) li))
  215.   )
  216.       )
  217.     )
  218.   (princ "\n-------(feng-wlkx-ssgettointer)---------\n")
  219.   (princ "\n-------------li-------------------------\n")
  220.   (princ li)
  221.   (princ "\n----------------------------------------\n")
  222.   (VL-SORT li '(LAMBDA (x y) (<= (DISTANCE p (car x)) (DISTANCE p (car y)))))
  223.   )
  224. ;-------------------------------------------------------;
  225. ;    选择通过对象的对象      ;
  226. ;              ;
  227. ;(feng-wlkx-sstossget 基准对象 前一个节点 当前节点)  ;
  228. ;              ;
  229. ;    返回(选集 逆时针端点)      ;
  230. ;-------------------------------------------------------;
  231. (defun feng-wlkx-sstossget ( s1 p p0 / p1 p2 p3 p4 param1 param2 pmin pmax n na ss )
  232.   (setq p1 (vlax-curve-getStartPoint s1)
  233.   p2 (vlax-curve-getEndPoint s1)
  234.   param1 (vlax-curve-getParamAtPoint s1 p0)
  235.   )
  236.   (if (<= (feng-3pointtoangle p p0 p1) (feng-3pointtoangle p p0 p2))
  237.     (setq param2 (vlax-curve-getStartParam s1)
  238.     p4 p1
  239.     )
  240.     (setq param2 (vlax-curve-getEndParam s1)
  241.     p4 p2
  242.     )
  243.     )
  244.   (setq p3 (vlax-curve-getPointAtParam s1 (/ (+ param1 param2) 2))
  245.   ss (ssget "f" (feng-3pointtosetnewxybox p0 p4 p3) '((0 . "LINE,ARC,CIRCLE")))
  246.   )
  247.   (repeat (setq n (sslength ss))
  248.     (if (= (vla-get-Handle (vlax-ename->vla-object (setq na (ssname ss (setq n (1- n)))))) (vla-get-Handle s1))
  249.       (setq ss (ssdel na ss))
  250.       )
  251.     )
  252.   (list ss p4)
  253. )
  254. ;-------------------------------------------------------;
  255. ;    根据对象对外包框进行转换旋转    ;
  256. ;              ;
  257. ;  (feng-3pointtosetnewxybox 原点 旋转点 目标点)  ;
  258. ;              ;
  259. ;    外包框向外扩一个单元      ;
  260. ;              ;
  261. ;    返回外包框列表(p1 p2 p3 p4)    ;
  262. ;-------------------------------------------------------;
  263. (defun feng-3pointtosetnewxybox ( p p2 p3 / p1 ang n li li1 xmin xmax ymin ymax )
  264.   (setq ang (angle p p2)
  265.   p2 (feng-xytomyxy p2 ang p)
  266.   p3 (feng-xytomyxy p3 ang p)
  267.   xmin (+ (min 0 (car p2) (car p3)) 2)
  268.   xmax (+ (max 0 (car p2) (car p3)) 1)
  269.   ymin (- (min 0 (cadr p2) (cadr p3)) 1)
  270.   ymax (+ (max 0 (cadr p2) (cadr p3)) 1)
  271.   li (list
  272.        (list xmin ymin 0)
  273.        (list xmin ymax 0)
  274.        (list xmax ymax 0)
  275.        (list xmax ymin 0)
  276.        )
  277.   li1 '()
  278.   )
  279.   (FOREACH n li (setq li1 (append li1 (list (feng-myxytoxy p ang n)))))
  280.   li1
  281.   )
  282. ;-------------------------------------------------------;
  283. ;           求以p2为角点,p1到p3的逆时针弧度            ;
  284. ;              ;
  285. ;  (feng-3pointtoangle 开始点 角点 终止点)    ;
  286. ;              ;
  287. ;  参考求3点逆时针角度.----by lxx.2007.2    ;
  288. ;              ;
  289. ;    返回逆时针弧度        ;
  290. ;-------------------------------------------------------;
  291. (defun feng-3pointtoangle ( p1 p2 p3 / ang li tmin tmax )
  292.   (setq li (list (angle p1 p2) (angle p3 p2))
  293.   tmin (apply 'min li)
  294.   tmax (apply 'max li)
  295.   ang (- tmax tmin)
  296.   )
  297.   (if (or (<= ang 1e-5) (<= (DISTANCE p1 p2) 1e-5) (<= (DISTANCE p3 p2) 1e-5))
  298.     (* 2 pi)
  299.     (if (= tmin (car li))
  300.       ang
  301.       (- (* 2 pi) ang)
  302.       )
  303.     )
  304.   )
  305. ;-------------------------------------------------------;
  306. ;      坐标系转换      ;
  307. ;              ;
  308. ;  (feng-xytomyxy 目标点 夹角 坐标系原点)    ;
  309. ;              ;
  310. ;  (feng-myxytoxy 目标点 夹角 坐标系原点)    ;
  311. ;              ;
  312. ;    返回计算后的坐标点      ;
  313. ;-------------------------------------------------------;
  314. ;-------------------------------------------------------;
  315. ;    标准坐标系===》》自定义坐标系    ;
  316. ;-------------------------------------------------------;
  317. (defun feng-xytomyxy ( p ang p0 / x y )
  318.   (setq x (+ (* (cos ang) (- (car p) (car p0))) (* (sin ang) (- (cadr p) (cadr p0)))))
  319.   (setq y (- (* (cos ang) (- (cadr p) (cadr p0))) (* (sin ang) (- (car p) (car p0)))))
  320.   (list x y 0)
  321.   )
  322. ;-------------------------------------------------------;
  323. ;    自定义坐标系==》》标准坐标系    ;
  324. ;-------------------------------------------------------;
  325. (defun feng-myxytoxy ( p ang p0 / x y )
  326.   (setq x (+ (- (* (car p0) (cos ang)) (* (cadr p0) (sin ang))) (car p)))
  327.   (setq y (+ (* (car p0) (sin ang)) (* (cadr p0) (cos ang)) (cadr p)))
  328.   (list x y 0)
  329.   )
  330. ;-------------------------------------------------------;
  331. ;    通过弧线计算凸度      ;
  332. ;              ;
  333. ;  (feng-wlkx-arctocon s1 p1 p2)      ;
  334. ;              ;
  335. ;    返回凸度        ;
  336. ;-------------------------------------------------------;
  337. (defun feng-wlkx-arctocon ( s1 p1 p2 / p3 ang td )
  338.   (setq p3 (vlax-curve-getPointAtParam s1 (/ (+ (vlax-curve-getParamAtPoint s1 p1) (vlax-curve-getParamAtPoint s1 p2)) 2))
  339.   ang (angle p1 p2)
  340.   p2 (feng-xytomyxy p2 ang p1)
  341.   p3 (feng-xytomyxy p3 ang p1)
  342.   td (- (/ (* 2 (cadr p3)) (car p2)))
  343.   )
  344.   td
  345.   )

本帖子中包含更多资源

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

x
发表于 2011-11-15 17:50:19 | 显示全部楼层
2012
好像运行不起来

命令:  ASDF
-------pointtossget-------
nil--->>>

然后就结束了
发表于 2011-11-15 18:20:34 | 显示全部楼层
论坛有highflybird大师的帖子哦
一个高效率的凸包算法!
http://bbs.mjtd.com/forum.php?mo ... &fromuid=398403
发表于 2011-11-15 18:26:04 | 显示全部楼层
命令: asdf
-------pointtossget-------
nil--->>>; 错误: 参数类型错误: lselsetp nil
网上有这方面的程序
 楼主| 发表于 2011-11-16 14:35:17 | 显示全部楼层
里面我没有加上对块和多段线的临时分解,呵。测试的时候,我只画了几条线,好像还不会出现这么惨的后果。一忙,都不知道编到哪了,呵。
发表于 2012-4-12 22:25:23 | 显示全部楼层
扩展一下 凸包算法,网上找到
http://wenku.baidu.com/view/46808150ad02de80d4d840cf.html

本帖子中包含更多资源

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

x
发表于 2015-6-2 19:36:07 | 显示全部楼层
外轮廓线和凸包不一样吧,外轮廓线可能是凹的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-20 01:29 , Processed in 0.193387 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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