明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 406|回复: 0

[讨论] @lisp敏捷开发方法论

  [复制链接]
发表于 2023-4-27 20:47 | 显示全部楼层 |阅读模式
本帖最后由 vitalgg 于 2023-4-27 20:57 编辑


原始链接https://mp.weixin.qq.com/s?__biz ... 5e7b2c6318bf835c#rd

* 从一个小需求说起
直接需求:求两个图层的线的交点形成圆

操作过程描述:提示选择第一个图层,然后提示选择第二个图层,然后选择图纸范围,范围内的图层一和图层二的线的交点形成圆形
* 编程关键点
1 选择第一个图层,
2 选择第二个图层,
3 然后选择图纸范围,
4 计算交点
5 绘制圆形

** 关键步骤功能点
*** 取得图层名
我们有两个方法取得图层名,1 从图层列表中选择。2 从图元对象得到图层名。

如果不知道怎么写代码,可以打开 CAD应用云 微信公众号。
输入要求查询有没有可用的函数。

*** 取得图纸范围
常用的是 ssget 的矩形和多边形选择。初始代码我们使用简单的矩形
#+begin_src lisp
  1. (ssget "w" pt1 pt2)

#+end_src

#+begin_src lisp
  1. (ssget "C" pt1 pt2)

#+end_src
*** 曲线交点
查询是否有可用的函数

*** 绘制圆形
由于命令创建圆和ActiveX方法创建圆的影响,不容易命中我们的@lisp函数要创建圆。输入 make-circle 也很容易搜到我们需要的函数。
* 组织代码
前面所有的技术问题都有解决的函数了。我们把这些函数组织到一起来完成需求

#+begin_src lisp
  1.   ;; 取第一、二个图层名
  2.   (setq layer1 (entity:get-layer (car (entsel))))
  3.   (setq layer2 (entity:get-layer (car (entsel))))
  4.   ;; 取图纸范围
  5.   (setq pt1 (getpoint "取图纸范围的第一个点"))
  6.   ;; 为了直观些,我们使用 getcorner 函数
  7.   (setq pt1 (getcorner pt1 "取图纸范围的第二个点"))

  8.   ;; 取图纸范围内的两个图层上的曲线

  9.   (setq ents1
  10.         (pickset:to-list
  11.          (ssget "c" pt1 pt2  (list (cons 0 (@:get-config '@curve:types))(cons 8 layer1)))))
  12.   (setq ents2
  13.         (pickset:to-list
  14.          (ssget "c" pt1 pt2  (list (cons 0 (@:get-config '@curve:types))(cons 8 layer2)))))

  15.   ;; 需求中要求不需要同一图层的曲线
  16.   (setq res nil)
  17.   (foreach ent1 ents1
  18.     (foreach ent2 ents2
  19.       (setq res (append res
  20.                     (curve:inters ent1 ent2 acextendnone)
  21.       ))))
  22.   ;; 去掉空值
  23.   (setq res (vl-remove nil res))

  24.   ;; 画圆,半径 50
  25.   (entity:make-circle res 50)

#+end_src
至此,基本的需求就完成了。

* 封装与迭代优化
将上面的过程封装成函数,私有化变量

#+begin_src lisp
  1.   (defun get-cross-from-2layer (/ layer1 layer2 pt1 pt2 ents1 ents2 res)
  2.     ;; 取第一、二个图层名
  3.     (setq layer1 (entity:get-layer (car (entsel))))
  4.     (setq layer2 (entity:get-layer (car (entsel))))
  5.     ;; 取图纸范围
  6.     (setq pt1 (getpoint "取图纸范围的第一个点"))
  7.     ;; 为了直观些,我们使用 getcorner 函数
  8.     (setq pt2 (getcorner pt1 "取图纸范围的第二个点"))

  9.     ;; 取图纸范围内的两个图层上的曲线

  10.     (setq ents1
  11.           (pickset:to-list
  12.            (ssget "c" pt1 pt2  (list (cons 0 (@:get-config '@curve:types))(cons 8 layer1)))))
  13.     (setq ents2
  14.           (pickset:to-list
  15.            (ssget "c" pt1 pt2  (list (cons 0 (@:get-config '@curve:types))(cons 8 layer2)))))

  16.     ;; 需求中要求不需要同一图层的曲线
  17.     (setq res nil)
  18.     (foreach ent1 ents1
  19.              (foreach ent2 ents2
  20.                       (setq res (append res
  21.                                         (curve:inters ent1 ent2 acextendnone)
  22.                                         ))))
  23.     ;; 去掉空值
  24.     (setq res (vl-remove nil res))
  25.     ;; 画圆,半径 50
  26.     (entity:make-circle res 50)
  27.     )

#+end_src

对于只使用了一次的符号变量,我们可以直接用表达式将其代替掉。

#+begin_src lisp
  1. (defun get-cross-from-2layer (/ layer1 layer2 pt1 pt2 ents1 ents2 res)
  2.     ;; 取第一、二个图层名
  3.     (setq layer1 (entity:get-layer (car (entsel))))
  4.     (setq layer2 (entity:get-layer (car (entsel))))
  5.     ;; 取图纸范围
  6.     (setq pt1 (getpoint "取图纸范围的第一个点"))
  7.     ;; 为了直观些,我们使用 getcorner 函数
  8.     (setq pt2 (getcorner pt1 "取图纸范围的第二个点"))

  9.     ;; 需求中要求不需要同一图层的曲线
  10.     (setq res nil)
  11.     (foreach ent1 (pickset:to-list
  12.                    (ssget "c" pt1 pt2  (list (cons 0 (@:get-config '@curve:types))(cons 8 layer1))))
  13.              (foreach ent2 (pickset:to-list
  14.                             (ssget "c" pt1 pt2  (list (cons 0 (@:get-config '@curve:types))(cons 8 layer2))))
  15.                       (setq res (append res
  16.                                         (curve:inters ent1 ent2 acextendnone)
  17.                                         ))))
  18.     ;; 去掉空值
  19.     (setq res (vl-remove nil res))
  20.     ;; 画圆,半径 50
  21.     (entity:make-circle res 50)
  22.     )
#+end_src

** 添加帮助说明,并加入到 @lisp 菜单系统

#+begin_src lisp
  1. (@:add-menu "@试验室" "层间线交点" '(@lab:get-cross-from-2layer))
  2.   (defun @lab:get-cross-from-2layer (/ layer1 layer2 pt1 pt2 ents1 ents2 res)
  3.     (@:help '("求两个图层的线的交点形成圆"
  4.               " 操作:选择第一个图层,然后提示选择第二个图层,然后选择图纸范围,范围内的图层一和图层二的线的交点形成圆形"))
  5.     ;; 取第一、二个图层名
  6.     (setq layer1 (entity:get-layer (car (entsel))))
  7.     (setq layer2 (entity:get-layer (car (entsel))))
  8.     ;; 取图纸范围
  9.     (setq pt1 (getpoint "取图纸范围的第一个点"))
  10.     ;; 为了直观些,我们使用 getcorner 函数
  11.     (setq pt2 (getcorner pt1 "取图纸范围的第二个点"))

  12.     ;; 需求中要求不需要同一图层的曲线
  13.     (setq res nil)
  14.     (foreach ent1 (pickset:to-list
  15.                    (ssget "c" pt1 pt2  (list (cons 0 (@:get-config '@curve:types))(cons 8 layer1))))
  16.              (foreach ent2 (pickset:to-list
  17.                             (ssget "c" pt1 pt2  (list (cons 0 (@:get-config '@curve:types))(cons 8 layer2))))
  18.                       (setq res (append res
  19.                                         (curve:inters ent1 ent2 acextendnone)
  20.                                         ))))
  21.     ;; 去掉空值
  22.     (setq res (vl-remove nil res))
  23.     ;; 画圆,半径 50
  24.     (entity:make-circle res 50)
  25.     )
#+end_src

* 发布
把上面的包括有菜单和功能函数的代码保存到一个单独的文件 get-cross-from-2layer.lsp ,并保存到 atlisp/packages/at-lab/ 目录下。

修改 @试验室 的包定义文件,加入 get-cross-from-2layer 到 定义的 :files 字段下。


增加版本号,使用 CAD下的 @lisp开发工具发布即可。






公众号文章:





本帖子中包含更多资源

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

x

评分

参与人数 2明经币 +4 金钱 +35 收起 理由
xyp1964 + 3 + 30 赞一个!
nsh935 + 1 + 5 赞一个!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-2 20:56 , Processed in 0.830971 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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