明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1324|回复: 19

[源码] 动态绘制闭合多边形---奇怪的现象---增加对象反应器以后,框内图元随多边形同步拉伸

[复制链接]
发表于 2021-12-28 19:44 | 显示全部楼层 |阅读模式
本帖最后由 masterlong 于 2022-3-28 23:21 编辑

正在编一个略微有点复杂的程序
远远没有完工
其中某个片段感觉还有点意思
先单独摘出来共享一下
源码放二楼

;=============================
给多边形增加了对象反应器以后
发生奇怪的事情
框内图元随对象拉伸操作同步拉伸
谁能解释下?

------------------------------------------------------------
上面的问题目前无解
怀疑是CAD的BUG
现在只有一个曲线救国的办法
框内目标图元全部复制原件删除


  1. (defun c:tt()
  2.   (if (setq ent (car (entsel))
  3.          *ent2obj*  vlax-Ename->Vla-Object
  4.          *obj2ent*  vlax-vla-object->ename
  5.          *acad*    (vlax-get-acad-object)
  6.     )
  7.     (setq dbpl_obj_Reactor (vlr-object-reactor (list (vlax-Ename->Vla-Object ent)) "" '((:vlr-modified . about_fw_xfs))))
  8.   )
  9. )
  10. ;;对象反应器
  11. (defun about_fw_xfs( theobj reactor parameter-list )
  12.   ;;是否已删除
  13.   (if (*obj2ent* theobj)
  14.     ;
  15.     ;有个奇怪的现象,为啥框内图元会随着多边形的拉伸操作(STRETCH命令拉伸多边形的某一段),同步执行“拉伸”   ?????????
  16.     ;
  17.     (progn
  18.       (zoomsave)
  19.       (setq theplent (*obj2ent* theobj))
  20.       (setq box (entbox theplent))
  21.       (zoomptlist box 1.5)
  22.       (setq theplptlist (massoc 10 theplent))
  23.       (setq ss (ssget "cp" theplptlist '((0 . "CIRCLE") (8 . "0") (62 . 3))))
  24.       (if ss
  25.         (princ (strcat "\n多边形内找到【 " (itoa (sslength ss)) " 】" ))
  26.         (princ "\n多边形内找到【 0 】")
  27.       )
  28.       (zoomload)
  29.     )
  30.   )
  31. (princ)
  32. )
  33. ;999当前视窗save
  34. (defun zoomsave()
  35.   (setq zoom*savelist (list (getvar "ctab") (vlax-3D-Point (trans (getvar "viewctr") 1 0)) (getvar "viewsize")))
  36. )
  37. ;999当前视窗load
  38. (defun zoomload()
  39.   (if zoom*savelist
  40.     (progn
  41.       (setvar "ctab" (car zoom*savelist))
  42.       (vla-ZoomCenter (vlax-get-acad-object) (trans (cadr zoom*savelist) 0 1) (caddr zoom*savelist))
  43.     )
  44.   )
  45. )
  46. ;;单个物体的最小(正交)包围框---------------------------------这个程序在遇到无法显示的图元时,还是会出错的,比如形。天正图元会不会也不支持,未测试
  47. (defun entbox ( ent / ll ur )
  48.   (vla-getboundingbox (*ent2obj* ent) 'll 'ur)
  49.   (mapcar 'vlax-safearray->list (list ll ur))
  50. )
  51. ;999以指定点表的包围框中心,缩放窗口——————主要用来保证后续可执行 (ssget 'CP/'WP ptlist)
  52. (defun zoomptlist( ptlist sc / box x midpo )
  53.   (setq box (npt2box ptlist))
  54.   (setq midpo (getmidpo box))
  55.   (vla-zoomwindow *acad* (vlax-3d-point (car box)) (vlax-3d-point (cadr box)))
  56.   (vla-ZoomScaled *acad* (/ 1.0 sc) 1)
  57. )
  58. ;999公共函数
  59. ;;求n个点的正交包围框
  60. ;;(setq npt (list p1 p2 p3 p4 ... ))
  61. (defun npt2box( npt )
  62.   (list
  63.     (apply 'mapcar (cons 'min npt))
  64.     (apply 'mapcar (cons 'max npt))
  65.   )
  66. )
  67. ;999公共函数
  68. ;;求点对中点
  69. (defun getmidpo( pts / P1 P2 X Y )
  70.   (setq p1 (car pts) p2 (cadr pts))
  71.   (if (= (length p1) (length p2))
  72.     nil
  73.     (setq p1 (list (car p1) (cadr p1))
  74.         p2 (list (car p2) (cadr p2))
  75.     )
  76.   )
  77.   (mapcar '(lambda (X Y) (/ (+ X Y) 2.0)) P1 P2)
  78. )



"觉得好,就打赏"
还没有人打赏,支持一下
 楼主| 发表于 2021-12-28 19:45 | 显示全部楼层
本帖最后由 masterlong 于 2021-12-29 18:49 编辑

;;dbx````动态绘制一个闭合的多边形.lsp
(defun c:dbx()
        (princ "dbx````动态绘制一个闭合的多边形,需要至少输入3个点....")
        (setq oldosmode (getvar "osmode"))
        (command "undo" "g")
        (if (and
                        (setq p1 (getpoint "\n指定第1点 : "))
                        (setvar "orthomode" 0)
                        (setq p2 (getpoint p1 "\n指定第2点 : "))
                        (setq ptlist (list p2 p1))
                        (princ "\n")
                        (if dyngrco dyngrco (setq dyngrco 7))
                )
                (progn
                        (setq yn_rppt NIL)
                        (setvar "osmode" 0)
                        (setq loop T)
                        (while loop
                                (princ "\r指定下一点 : ")
                                (setq gr (grread T 15 2))
                                (setq grpt (cadr gr)
                                                mode (car  gr)
                                )
                                ;;pickbox的大小```因为视窗大小在变化,所以dist的具体数值也是变化的
                                (setq dist (* (/ (getvar "pickbox") (cadr (getvar "screensize"))) (getvar "viewsize")))
                                
                                (cond
                                        ((= mode 5)                                                 (db_dbx_5_grpt))                                ;;动态多边形
                                        ((= mode 3)                                                 (db_dbx_3_putapt))                        ;;左键定点
                                        ((or (= mode 11)(= mode 2))         (db_dbx_11_rightclick))                ;;右键结束
                                        ( T (setq loop NIL) (redraw))                                                                                ;;其它中止
                                )
                        )
                )
        )
(princ)
)

;1`1动态多边形
(defun db_dbx_5_grpt()
        (redraw)
        (setq grptlist (cons grpt ptlist))
        ;;动态多边形时,若鼠标移至ptlist某一点时,自动取代这个点【貌似ok】
        (db_dbx_5_autorppt)
        (grdraw_pline_co ptlist dyngrco)
        (grdraw p1 grpt 6 1)
        (grdraw p2 grpt 6 1)
)
;1`2左键定点
(defun db_dbx_3_putapt()
        (redraw)
        (setq p3 grpt)
        (setq p2 p3)
        (setq ptlist (cons p3 ptlist))
        (grdraw_pline_co ptlist dyngrco)
        (setq yn_rppt NIL)                        ;;每次定点,重置自动取代
)
;1`3右键结束
(defun db_dbx_11_rightclick()
        (redraw)
        (emkpline ptlist dyngrco)
        (setq loop NIL)
)

;1`1`1动态多边形时,若鼠标移至ptlist某一点时,自动取代这个点
(defun db_dbx_5_autorppt()
        ;;动态坐标超过一定距离以后,自动取代功能生效
        (if (>= 3 (length grptlist))
                (setq yn_rppt NIL)
                (if (< (* 5 dist) (distance grpt p2)) (setq yn_rppt T))
        )
        (if yn_rppt
                (if (setq tmp (vl-some ''((pt) (< (distance grpt pt) (* 0.5 dist))) ptlist))
                        (progn
                                (setq rept (car (vl-sort ptlist ''((a b) (< (distance grpt a) (distance grpt b))))))
                                (setq id (vl-position rept ptlist))
                                (setq biao1 (listsub ptlist 0 id)
                                                biao2 (listsub ptlist (1+ id) (length ptlist))
                                )
                                (setq ptlist (append biao2 biao1))
                                (setq p1 (last ptlist)
                                                p2 (car  ptlist)
                                )
                                ;;生效一次以后,自动取代功能失效
                                (setq yn_rppt NIL)
                        )
                )
        )
)

;;按指定颜色生成闭合PL线````70必须在90后面
(defun emkpline( pts co )
(entmake (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 62 co) (cons 90 (length pts)) '(70 . 1))
           (mapcar '(lambda (pt)(cons 10 pt)) pts)
        )
  )
)
;;一个坐标集绘制虚拟闭合线
(defun grdraw_pline_co( pts co / ucspts p1 p2 )
        (setq ucspts pts)
        (mapcar ''((p1 p2) (grdraw p1 p2 co 0)) (cdr ucspts) ucspts)
        (grdraw (car ucspts) (last ucspts)  2 1)
)

;;截取列表的一部分  i=目标子元素的id  len=截取的子表个数`````待优化
(defun listsub ( biao i len / a temp one )
(if (and
   (= (type i) 'INT)
   (>= i 0)
  )
  (progn
   (if (or (null len) (< len 0))
    (setq len (length biao))
   )
   (setq a 0)
   (setq temp '())
   (repeat (length biao)
    (setq one (car biao))
    (setq biao (cdr biao))
    (if (and (>= a i) (< a (+ len i)))
     (setq temp (cons one temp))
    )
    (setq a (1+ a))
   )
   (setq biao '())
   (repeat (length temp)
    (setq one (car temp))
    (setq temp (cdr temp))
    (setq biao (cons one biao))
   )
  )
)
)

评分

参与人数 1明经币 +1 收起 理由
bssurvey + 1 赞一个!

查看全部评分

 楼主| 发表于 2021-12-29 18:50 | 显示全部楼层
谢谢
2楼也已更新


;;截取列表的一部分  i=目标子元素的id  len=截取的子表个数
(defun listsub ( biao i len / a temp one )
        (if (and
                        (= (type i) 'INT)
                        (>= i 0)
                )
                (progn
                        (if (or (null len) (< len 0))
                                (setq len (length biao))
                        )
                        (setq a 0)
                        (setq temp '())
                        (repeat (length biao)
                                (setq one (car biao))
                                (setq biao (cdr biao))
                                (if (and (>= a i) (< a (+ len i)))
                                        (setq temp (cons one temp))
                                )
                                (setq a (1+ a))
                        )
                        (setq biao '())
                        (repeat (length temp)
                                (setq one (car temp))
                                (setq temp (cdr temp))
                                (setq biao (cons one biao))
                        )
                )
        )
)

 楼主| 发表于 2021-12-28 19:45 | 显示全部楼层
本帖最后由 masterlong 于 2021-12-28 20:01 编辑

这样做的现实意义么
跟我在编的这个程序功能有关

火灾自动报警平面设计
有一条规范
一个回路不能超过32个点
考虑预留一般限定在25~28之间
这样就经常需要测算实际绘制的点数

我的程序构想是
动态绘制多边形的同时
计算多边形框内消防点数
由于建筑平面的复杂性
多边形的绘制过程中
反复调整多边形界线的概率比较高
动态取代的功能设置
可以大大减少绘制完成后的二次调整

 楼主| 发表于 2021-12-28 19:45 | 显示全部楼层
本帖最后由 masterlong 于 2021-12-28 19:51 编辑

二楼代码的重点
动态绘制时
若鼠标移动到已有某一点的附近时
会自动取消该点
这样比较方便多边形的即时调整
 楼主| 发表于 2021-12-28 19:46 | 显示全部楼层
本帖最后由 masterlong 于 2021-12-28 20:06 编辑

整个程序完工以后会共享出来
先把楼占着

动态统计消防点位这个不难
麻烦的是统计数据的实时展示
只靠命令行输出有点难搞
决定上odcl的非模式对话框
同时辅以多边形变色

 楼主| 发表于 2021-12-28 19:46 | 显示全部楼层
本帖最后由 masterlong 于 2021-12-28 20:12 编辑

绘制的动态多边形
实际上就是取得一个点集
计划在取得点集以后再增密
这样生成的多边形
便于设计过程的后期调整

同时准备再添加反应器
多边形改变顶点位置以后
自动复核框内点数


目前进度可能不到1/20
发表于 2021-12-28 23:53 | 显示全部楼层
期待大作发布!!!
发表于 2021-12-29 08:00 | 显示全部楼层
很棒的一個想法和做法,可以省去很多做圖的時間
发表于 2021-12-29 10:08 | 显示全部楼层
谢谢分享
先点赞,标记
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-2 07:09 , Processed in 1.078758 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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