明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 781|回复: 18

[经验] 以面向对象的概念设计lisp函数

[复制链接]
发表于 2024-6-12 16:37 | 显示全部楼层 |阅读模式
本帖最后由 和尚777 于 2024-6-12 16:56 编辑
以面向对象的基本概念设计你的lisp函数

; 以最常用的实体包围盒为例
  1. (defun c:t2 (/ e p1 p5 p7)
  2.   (if(and(setq e(car(entsel)))
  3.        (setq p1 (hs-Ent9pt e 1)) ; 传统方式,每次都要重新获取包围盒
  4.        (setq p5 (hs-Ent9pt e 5))
  5.        (setq p7 (hs-Ent9pt e 7)) ; 获取了3次
  6.      )
  7.     (progn     
  8.       (mk-circle p1 10)
  9.       (mk-circle p5 10)
  10.       (mk-circle p7 10)
  11.       
  12.     )
  13.   )(princ)
  14. )
; 进阶做法
  1. (defun c:t3 (/ e lst p1 p5 p7)
  2.   (if(and(setq e(car(entsel)))
  3.       (setq lst(hs-AssocCdr "list"(hs-BoundingBoxInfo e))) ; 进阶做法,获取包围盒9点列表
  4.       
  5.      )
  6.     (progn
  7.       (setq p1 (nth 0 lst)) ; 不会重复获取包围盒
  8.       (setq p5 (nth 4 lst)) ; 按索引取值,忘了其意义就要去看表是怎么获取的,表结构是什么
  9.       (setq p7 (nth 6 lst))
  10.       (mk-circle p1 10)
  11.       (mk-circle p5 10)
  12.       (mk-circle p7 10)
  13.       
  14.     )
  15.   )(princ)
  16. )
; 面向对象的方式
  1. (defun c:t1 (/ e lst p1 p5 p7)
  2.   (if(and(setq e(car(entsel)))
  3.       (setq lst (hs-BoundingBoxInfo e)) ; 获取包围盒信息
  4.       
  5.      )
  6.     (progn
  7.       (setq p1 (hs-AssocCdr "p1" lst)) ; 从信息中以key获取值,意义明确,把key当做对象的属性
  8.       (setq p5 (hs-AssocCdr "p5" lst)) ; 不会重复获取包围盒
  9.       (setq p7 (hs-AssocCdr "p7" lst)) ; 更好的操作和利用数据
  10.       (mk-circle p1 10)
  11.       (mk-circle p5 10)
  12.       (mk-circle p7 10)
  13.       (princ (hs-AssocCdr "area" lst))
  14.     )
  15.   )(princ)
  16. )
  1. ; 和一般的以9位码获取坐标函数相同,获取包围盒只返回一个坐标
  2. ; 包围盒9位码坐标
  3. ; P7---------------P8----------------P9
  4. ; |                |                 |
  5. ; |                |                 |
  6. ; |                |                 |
  7. ; P4---------------P5----------------P6
  8. ; |                |                 |
  9. ; |                |                 |
  10. ; |                |                 |
  11. ; P1---------------P2----------------P3

  12. (defun hs-Ent9pt(ent i / lst)
  13.   (setq lst(hs-AssocCdr "list"(hs-BoundingBoxInfo ent))) ; 不想再写个函数,所以从info里取
  14.   (nth (- i 1) lst)
  15. )
  1. ; (hs-Subst "1" 22 '(("0" . 0)("1" . 1)("2" . 2)))
  2. ; 修改关联表的值,返回表
  3. (defun hs-Subst(key value lst)
  4.   (if(and key value lst
  5.        (setq key(strcase key))
  6.        (setq lst(hs-Uppercase lst))
  7.         
  8.      )
  9.     (progn
  10.       (subst (cons key value) (assoc key lst) lst)
  11.     )
  12.   )
  13. )
  1. ; key大写
  2. (defun hs-Uppercase(lst)
  3.   (if (and lst(listp lst))
  4.     (mapcar
  5.       (function
  6.         (lambda(x)
  7.           (cons(strcase (car x) )(cdr x))
  8.         )
  9.       )
  10.       lst
  11.     )   
  12.   )
  13. )
  1. ; 获取关联点对表的值,忽略大小写
  2. (defun hs-AssocCdr(a lst)
  3.   (if(and a lst (listp lst))
  4.     (progn      
  5.       (cdr
  6.         (assoc
  7.           (strcase a)
  8.           (hs-Uppercase lst)
  9.         )        
  10.       )
  11.     )
  12.   )
  13. )
  1. ; 获取实体包围盒信息
  2. ; 返回信息关联点对表
  3. (defun hs-BoundingBoxInfo(ent / p1 p9)
  4.   (if(and (setq pts (hs-GetBox ent))
  5.        (listp pts)
  6.        (setq p1 (car pts))
  7.        (setq p9 (cadr pts))
  8.        (listp p1)(listp p9)      
  9.      )
  10.     (progn
  11.       (hs-BoundingBox p1 p9)
  12.     )
  13.   )
; 把返回的结果设计成点对表结构,就像dxf码那样
  1. ; 获取包围盒信息关联点对表
  2. ; 返回的列表就像一个对象,width是属性
  3. (defun hs-BoundingBox(p1 p9 / height p2 p3 p4 p5 p6 p7 p8 width)
  4.   (if(and p1 p9(listp p1)(listp p9))
  5.     (progn
  6.       (setq p5 (hs-PointMid p1 p9)
  7.         p3 (if (< (car p9) (car p1))
  8.              (list (car p1) (cadr p9) (caddr p1))
  9.              (list (car p9) (cadr p1) (caddr p1))
  10.            )
  11.         p7 (if (< (car p9) (car p1))
  12.              (list (car p9) (cadr p1) (caddr p9))
  13.              (list (car p1) (cadr p9) (caddr p9))
  14.            )
  15.         p2 (hs-PointMid p1 p3)
  16.         p4 (hs-PointMid p1 p7)
  17.         p6 (hs-PointMid p3 p9)
  18.         p8 (hs-PointMid p7 p9)
  19.         width(distance p1 p3)
  20.         height(distance p1 p7)
  21.         area(* width height)
  22.       )
  23.       (list   
  24.         (cons "p6" p6) ; 不按顺序构建表,assoc能获取到
  25.         (cons "p7" p7) ; 和尚777
  26.         (cons "p8" p8)
  27.         (cons "p9" p9)
  28.         
  29.         (cons "p1" p1)
  30.         (cons "p2" p2)
  31.         (cons "p3" p3)
  32.         (cons "p4" p4)
  33.         (cons "p5" p5)      
  34.         (cons "width" width)
  35.         (cons "height" height)
  36.         (cons "area" area)
  37.         (cons "list" (list p1 p2 p3 p4 p5 p6 p7 p8 p9 width height area)) ; 表顺序不能错
  38.       )      
  39.     )
  40.   )
  41. )

  1. ; 两点之中点
  2. (defun hs-PointMid (p1 p2)
  3.   (if (and p1 p2(listp p1)(listp p2))
  4.     (mapcar
  5.       '(lambda (x)
  6.          (* x 0.5)
  7.        )
  8.       (mapcar '+ p1 p2)   
  9.     )
  10.   )
  11. )

  12. ; 包围盒2点列表
  13. (defun hs-GetBox(ent / MinPt MaxPt)  
  14.   (if ent
  15.     (progn
  16.       (vla-getboundingbox (vlax-ename->vla-object ent) 'MinPt 'MaxPt)
  17.       (list (vlax-safearray->list MinPt)
  18.         (vlax-safearray->list MaxPt)
  19.       )
  20.     )
  21.   )
  22. )

  23. ; 创建圆
  24. (defun mk-Circle (cen r)
  25.   (entmakeX (list '(0 . "CIRCLE") (cons 10 cen) (cons 40 r))))




本帖子中包含更多资源

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

x

评分

参与人数 4明经币 +4 金钱 +60 收起 理由
hubeiwdlue + 1 赞一个!
fangmin723 + 1 + 50 很给力!
tomonkey239 + 1
tryhi + 1 + 10 赞一个!

查看全部评分

发表于 2024-6-13 13:06 来自手机 | 显示全部楼层
kozmosovia 发表于 2024-6-12 19:14
其实没啥用,首先,不见得有需要重复算N的操作,真需要了,最合理的选择是定义一个变量保存第一次的计算结 ...

赞同,张元英扭屁股、跳舞很流行,很多人喜欢,非常有美感。但你让张元英来唱宋祖英的歌曲,把扭屁股强加进来,其实真没啥用。估计老江都受不了
发表于 2024-6-19 20:12 | 显示全部楼层
list就可以,就12个数,car类函数可以到第四个和最后一个,就算list中12个数值,也就是最多3个函数串,可做函数car5~car11。
其实极少极少情况用到12个数值。最多是四角+中间的5点。刚好lisp有对应的位置函数。
发表于 2024-6-12 19:14 | 显示全部楼层
其实没啥用,首先,不见得有需要重复算N的操作,真需要了,最合理的选择是定义一个变量保存第一次的计算结果,以后从里面提取数据。所以,没必要面向对象,面向变量就行。
发表于 2024-6-12 17:28 | 显示全部楼层
函数不能重载,太限制了
发表于 2024-6-12 19:01 | 显示全部楼层
感谢大佬的热心分享
发表于 2024-6-12 19:02 | 显示全部楼层
不明觉厉+1~~~~~~~
发表于 2024-6-12 20:29 | 显示全部楼层
索引法用好了,速度飞快
发表于 2024-6-12 20:49 | 显示全部楼层
感谢和尚777大佬的分享!
发表于 2024-6-12 21:07 | 显示全部楼层
授人以渔,鼓掌鼓掌
发表于 2024-6-13 09:05 | 显示全部楼层
厉害了,有思路有码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-6-21 13:43 , Processed in 0.164423 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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