明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1251|回复: 4

[源码] Autolisp实现凸包算法

  [复制链接]
发表于 2023-5-16 20:55:33 | 显示全部楼层 |阅读模式

写了个凸包算法的autolisp实现,采用Graham扫描法,供大家学习参考
有需求自取!

  1. (defun c:tt()
  2.   (L-entity-creatnline nil (l-point-convexpolygon (setq pt_lst (mapcar '(lambda(x)(cdr (assoc 10 (entget x)))) (L-sel->list (ssget '((0 . "POINT"))))))))
  3. )

  4. ;;;-----------------------------------------------------------;;
  5. ;;; 获取点集的凸包
  6. ;;;-----------------------------------------------------------;;
  7. ;;; L-point-convexpolygon
  8. ;;; 输入: pt_lst>>>点集
  9. ;;; 输出: 多边形点集
  10. ;;; 示例:
  11. ;;;-----------------------------------------------------------;;
  12. ;;;-----------------------------------------------------------;;
  13. (defun L-point-convexpolygon(pt_lst)
  14.   (if (> (length pt_lst) 3)
  15.     (progn
  16.       (setq pt0 (car (setq pt_lst (vl-sort pt_lst '(lambda (p1 p2) (< (cadr p1) (cadr p2)) )))))
  17.       (setq pt_lst (vl-sort pt_lst '(lambda (p1 p2) (< (angle '(0 0 0) (L-point-subtract p1 pt0) ) (angle '(0 0 0) (L-point-subtract p2 pt0))))))
  18.       (setq i 0)
  19.       (setq res (append (list (cadr pt_lst)) (list (car pt_lst)) ))
  20.       (setq pt_lst (L-list-getnvalue pt_lst 2 (length pt_lst)))
  21.       (while (< i (length pt_lst))
  22.         (cond
  23.           ((> (L-point-positiononline (nth i pt_lst)  (nth 1 res) (nth 0 res)) 0)
  24.             (setq res (append (list (nth i pt_lst)) res))
  25.           )
  26.           ((< (L-point-positiononline (nth i pt_lst)  (nth 1 res) (nth 0 res)) 0)
  27.             (setq res (L-list-getnvalue res 1 (length pt_lst)))
  28.             (while  (< (L-point-positiononline (nth i pt_lst)  (nth 1 res) (nth 0 res)) 0)
  29.                     (setq res (L-list-getnvalue res 1 (length pt_lst)))
  30.             )
  31.             (setq res (append (list (nth i pt_lst)) res))
  32.           )
  33.           ((= (L-point-positiononline (nth i pt_lst)  (nth 1 res) (nth 0 res)) 0)
  34.             (setq res (L-list-getnvalue res 1 (length pt_lst)))
  35.             (setq res (append (list (nth i pt_lst)) res))
  36.           )
  37.         )
  38.         (setq i (1+ i))
  39.       )
  40.       (setq res (append (list (nth (- (length pt_lst) 1) pt_lst)) res))
  41.     )
  42.     (setq res pt_lst)
  43.   )
  44. )

  45. ;;;-----------------------------------------------------------;;
  46. ;;; 判断点在直线左侧、右侧、直线上
  47. ;;;-----------------------------------------------------------;;
  48. ;;; L-point-positiononline
  49. ;;; 输入: pt>>>需要判断的点
  50. ;;;       pt1>>>直线起点
  51. ;;;       pt2>>>直线终点
  52. ;;; 输出:等于0>在直线上,小于0>在直线右侧,大于0>在直线左侧
  53. ;;; 示例:
  54. ;;;-----------------------------------------------------------;;
  55. ;;;-----------------------------------------------------------;;
  56. (defun L-point-positiononline(pt pt1 pt2)
  57.   (- (*(-(car pt1) (car pt))(- (cadr pt2) (cadr pt))) (*(-(car pt2) (car pt))(- (cadr pt1) (cadr pt))))
  58. )

  59. ;;;-----------------------------------------------------------;;
  60. ;;; 两点加法
  61. ;;;-----------------------------------------------------------;;
  62. ;;; L-Point-Add、L-Point-subtract
  63. ;;; 输入:
  64. ;;; 输出:
  65. ;;; 示例:
  66. ;;;-----------------------------------------------------------;;
  67. ;;;-----------------------------------------------------------;;
  68. (defun L-point-subtract(PT1 PT2)
  69.   (list (-(car pt1) (car pt2)) (-(cadr pt1) (cadr pt2)) (-(caddr pt1) (caddr pt2)))
  70. )

  71. ;;;-----------------------------------------------------------;;
  72. ;;; 获取列表指定区间的值
  73. ;;;-----------------------------------------------------------;;                                   
  74. ;;; L-list-getnvalue                                       
  75. ;;; 输入:m>>>起点位置 列表第一位为0
  76. ;;;       n>>>结束位置
  77. ;;; 输出:                                    
  78. ;;; 示例:
  79. ;;;-----------------------------------------------------------;;
  80. (defun L-list-getnvalue (lst m n / res i)
  81.   (setq res nil)
  82.   (if (and (= (type m) 'INT) (= (type n) 'INT))
  83.     (progn
  84.       (setq i m)
  85.       (while (and (setq l (nth i lst)) (< i (+ n m)))
  86.         (setq res (append res (list l)))
  87.         (setq i (1+ i))
  88.       )
  89.     )
  90.   )
  91.   res
  92. )

  93. ;;;-----------------------------------------------------------;;
  94. ;;; 创建直线                                   
  95. ;;; L-entity-creatline                                       
  96. ;;; 输入:                                          
  97. ;;; 输出:
  98. ;;; 示例:
  99. ;;;-----------------------------------------------------------;;
  100. (defun L-entity-creatline (lay pt1 pt2)
  101.   (if (null lay)
  102.     (entmakex (list (cons 0 "LINE") (cons 8 (getvar 'clayer)) (cons 10 pt1) (cons 11 pt2)))
  103.     (entmakex (list (cons 0 "LINE") (cons 8 lay) (cons 10 pt1) (cons 11 pt2)))
  104.   )
  105. )
  106. (defun L-entity-creatnline (lay l_lst / i res)
  107.   (setq i 0)
  108.   (setq res nil)
  109.   (if (null lay)
  110.     (repeat (- (length l_lst) 1)
  111.       (setq res (append res (list (entmakex (list (cons 0 "LINE") (cons 8 (getvar 'clayer)) (cons 10 (nth i l_lst)) (cons 11 (nth (setq i (1+ i)) l_lst)))))))
  112.     )
  113.     (repeat (- (length l_lst) 1)
  114.       (setq res (append res (list (entmakex (list (cons 0 "LINE") (cons 8 lay) (cons 10 (nth i l_lst)) (cons 11 (nth (setq i (1+ i)) l_lst)))))))
  115.     )
  116.   )
  117. )

  118. ;;;-----------------------------------------------------------;;
  119. ;;; 列表、选择集互转
  120. ;;;-----------------------------------------------------------;;
  121. ;;; L-sel->list  L-list->sel                             
  122. ;;; 输入:
  123. ;;; 输出:
  124. ;;; 示例:
  125. ;;;-----------------------------------------------------------;;
  126. (defun L-sel->list(sel / res i)
  127.   (setq res nil)
  128.   (setq i 0)
  129.   (if (/= sel nil)  
  130.     (repeat (sslength sel)
  131.       (setq res (append res (list (ssname sel i))))
  132.       (setq i (1+ i))
  133.     )
  134.   )
  135.   res
  136. )
  137. (defun L-list->sel (lst / res)
  138.   (setq res (ssadd))
  139.   (foreach l lst (setq res (ssadd l res)))
  140. )
  141. (princ)

本帖子中包含更多资源

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

x

评分

参与人数 4明经币 +4 金钱 +30 收起 理由
hhh454 + 1 + 10 赞一个!
bssurvey + 1 赞一个!
USER2128 + 1 赞一个!
tigcat + 1 + 20 谢谢分享算法.给力

查看全部评分

发表于 2023-5-17 06:39:11 | 显示全部楼层




发表于 2023-5-17 10:27:25 | 显示全部楼层
感谢分享算法,学习了
发表于 2023-5-20 08:44:58 | 显示全部楼层
;;; 判断点在直线左侧、右侧、直线上
;;; L-point-positiononline

;注意该子程序理论上不严谨,可能产生错误;
发表于 2023-5-22 21:13:03 | 显示全部楼层

这个视频怎么发布的呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-16 18:55 , Processed in 0.186293 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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