找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

楼主: Lisper

[研讨] 关于如何计算XClip剪裁边界顶点坐标的研究

[复制链接]

已领礼包: 593个

财富等级: 财运亨通

发表于 2013-5-24 00:21:02 来自手机 | 显示全部楼层
对于开关 也就是0 1 用一个程序即可,0的话变1,1的话变0来自: iPhone客户端
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-5-24 00:49:48 | 显示全部楼层
eachy 发表于 2013-5-24 00:21
对于开关 也就是0 1 用一个程序即可,0的话变1,1的话变0

咋用手机了,上床了啊。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-5-24 10:59:37 | 显示全部楼层
本帖最后由 牢固 于 2013-5-24 12:34 编辑

搞清楚了XCLIP剪裁边界的内在机制,下面要重新修改剪裁块的边界就很容易了。我们来看,11楼的代码由剪裁块计算出顶点的坐标是这样一个过程:
1、通过SPATIAL_FILTER对象,得到剪裁边界的原始定义顶点坐标表PL和该坐标转换到图块定义的转换矩阵M
2、通过图块计算出图块的BlockDef->BlockRef的转换矩阵M1
3、PL经过M和M1两次矩阵转换,就得到了剪裁边界的WCS坐标
重构剪裁边界,就是上述过程的一个逆过程:

1、根据图块计算出图块的BlockRef->BlockDef矩阵,即图块的逆矩阵M0
2、将新边界的顶点WCS坐标PL根据Mo矩阵转换到图块的定义坐标系
3、通过SPATIAL_FILTER对象,得到剪裁边界的原始定义顶点转换到图块定义的转换矩阵M1,并计算出M2的逆矩阵
4、再将第二步转换后的PL经过M2矩阵转换,转换到剪裁边界的原始定义坐标系
5、用新的PL坐标表更新SPATIAL_FILTER对象的的10组码表,并根据PL顶点个数更新70组码
6、更新显示图块

                               
登录/注册后可看大图

相关矩阵函数参见高飞鸟的帖子:Lisp论矩阵
  1. ;;修改XCLIP边界
  2. (defun c:tt ()
  3.   (while
  4.     (and
  5.       (setq e (car(entsel "\n选择剪裁块:")))
  6.       (setq Poly (car(entsel "\n选择剪裁边界:")))
  7.       )
  8.     (gxl-EditXclipBoundary e poly)
  9.     )
  10.   (princ)
  11.   )

  12. ;;(gxl-EditXclipBoundary ENAME BOUNDARY) 重构XCLip的剪裁边界,参数 ENAME=剪裁块图元 BOUNDARY=点表或多段线图元
  13. ;;(gxl-EditXclipBoundary (car(entsel "\n选择剪裁块:")) (car(entsel "\n选择剪裁边界:")))
  14. (defun gxl-EditXclipBoundary (ENAME BOUNDARY        /       ISXCLIP
  15.                                     PTLIST  PLIST   EL      M0
  16.                                     DXF40   M1      M       N
  17.                                     )
  18.   (defun IsXClip (ename / xdict)
  19.     (if
  20.       (setq xdict (cdr (assoc 360 (entget ename))))
  21.        (IsXClip xdict)
  22.        (if
  23.          (eq "SPATIAL_FILTER"
  24.                (cdr (assoc 0 (setq ename (entget ename))))
  25.                )
  26.           ename
  27.           )
  28.        )
  29.     )
  30.   (if (= 'ename (type Boundary))
  31.     (setq PList (gxl-get_poly_ptList3 Boundary 0.05))
  32.     (if (= 'list (type Boundary))
  33.       (setq pList Boundary)
  34.       )
  35.     )
  36.   (if (and (setq el (IsXCLIP ename))
  37.            PList
  38.            )
  39.     (progn
  40.       ;;计算图块的逆转换矩阵 Ref-> Del
  41.       (setq m0 (apply 'MAT:DISPTOMATRIX (MAT:RevRefGeom ename)))
  42.       ;;计算剪切边界顶点转换到图块定义的矩阵
  43.       (setq dxf40 (vl-remove-if-not '(lambda (x) (= (car x) 40)) el) ) ;_ 矩阵数据表     (if (= 1 (cdr (assoc 72 el))) (setq dxf40 (cdr dxf40)))
  44.       (setq m1
  45.              (list
  46.                (mapcar 'cdr
  47.                        (list (nth 0 dxf40)
  48.                              (nth 1 dxf40)
  49.                              (nth 2 dxf40)
  50.                              (nth 3 dxf40)
  51.                              )
  52.                        )
  53.                (mapcar 'cdr
  54.                        (list (nth 4 dxf40)
  55.                              (nth 5 dxf40)
  56.                              (nth 6 dxf40)
  57.                              (nth 7 dxf40)
  58.                              )
  59.                        )
  60.                (mapcar 'cdr
  61.                        (list (nth 8 dxf40)
  62.                              (nth 9 dxf40)
  63.                              (nth 10 dxf40)
  64.                              (nth 11 dxf40)
  65.                              )
  66.                        )
  67.                '(0 0 0 1)
  68.                )
  69.             )
  70.       ;;矩阵m1求逆,计算出图块定义坐标变换到剪切边界的定义坐标系
  71.       (setq m1 (Mat:Inverse m1))
  72.       ;;计算坐标PList经过m0 m1 矩阵变换到剪切边界的定义坐标系的矩阵
  73.       (setq m (MAT:MXM m1 m0))
  74.       ;;计算PList经过矩阵m变换后的坐标
  75.       (setq PList (mapcar '(lambda (x) (MAT:MXP m x)) Plist))
  76.       (setq n (length PList)) ;_ 剪切边界的顶点数
  77.       (setq el (subst (cons 70 n) (assoc 70 el) el))
  78.       (setq el
  79.              (append
  80.                (reverse (member (assoc 70 el) (reverse el)))
  81.                (mapcar '(lambda (x) (cons 10 x)) PList)
  82.                (member (assoc 210 el) el)
  83.                )
  84.             )
  85.       ;;更新边界
  86.       (entmod el)
  87.       (entupd ename) ;_ 更新图块
  88.       )
  89.     )
  90.   )
  91. ;;;gxl-get_poly_ptList3 返回多义线顶点点列表,有圆弧则用一定角度分割圆弧,闭合多义线点表不含闭合点坐标
  92. (defun gxl-get_poly_ptList3 (ENT FGX  /      OBJNAME       VERTEXSNUM
  93.          N  PT     PLIST  SECDEV BUGLE
  94.          BJ  D1     D2     D       K
  95.          D0  PARAM
  96.         )
  97.   (setq objname
  98.    (cond
  99.      ((GXL-CATCHAPPLY vla-get-ObjectName (list ent)))
  100.      ((GXL-CATCHAPPLY gxl-dxf (list ent 0)))
  101.      )
  102.   )
  103.   (setq  vertexsNum
  104.    (fix (vlax-curve-getEndParam ent))
  105.   n 0
  106.   ) ;_ 结束setq
  107.   (cond  ((or
  108.      (= "AcDbCircle" objname)
  109.      (= "CIRCLE" objname)
  110.      )
  111.    (if (equal fgx 0 1e-6)
  112.      (setq fgx pi2)
  113.    )
  114.    (setq vertexsNum
  115.     (fix (/ 2pi fgx))
  116.          n 0
  117.    )
  118.    (repeat vertexsNum
  119.      (setq pt (vlax-curve-getPointAtParam ent (* n fgx)))
  120.      (setq plist (cons pt plist)
  121.      n     (1+ n)
  122.      )
  123.    )
  124.    (reverse plist)

  125.   )
  126.   (t
  127.    (if (or
  128.          (= "AcDb2dPolyline" objName)
  129.          (= "POLYLINE" objName)
  130.          )
  131.      (progn
  132.        (repeat vertexsNum
  133.          (setq pt (vlax-curve-getPointAtParam ent n))
  134.          (setq plist (cons pt plist))
  135.          (setq pt (vlax-curve-getPointAtParam ent (+ 0.25 n)))
  136.          (setq plist (cons pt plist))
  137.          (setq pt (vlax-curve-getPointAtParam ent (+ 0.5 n)))
  138.          (setq plist (cons pt plist))
  139.          (setq pt (vlax-curve-getPointAtParam ent (+ 0.75 n)))
  140.          (setq plist (cons pt plist))
  141.          (setq n (1+ n))
  142.        )
  143.        (if (not (vlax-curve-isClosed ent))
  144.          (setq plist (cons (vlax-curve-getEndPoint ent) plist))
  145.        ) ;_ 结束if
  146.        (reverse plist)

  147.      )
  148.            
  149.      (if (equal fgx 0 1e-6)
  150.              (progn
  151.                (if (= 'ename (type ent)) (setq ent (vlax-ename->vla-object ent)))
  152.                (setq h (list(cdr (assoc 38 (setq ent (entget ent))))))
  153.        (mapcar '(lambda (a) (cdr (append a h))) (vl-remove-if-not '(lambda (x) (= 10 (car x))) ent))
  154.                )
  155.        (progn
  156.          
  157.          (repeat vertexsNum
  158.      (if (setq secdev (vlax-curve-getSecondDeriv ent n))
  159.        (progn
  160.      (setq pt    (vlax-curve-getPointAtParam ent n)
  161.            bugle (vla-GetBulge ent n)
  162.      ) ;_ 结束setq
  163.      (setq plist (cons pt plist))
  164.      (if (/= bugle 0.0)
  165.        (progn
  166.          (setq bj (* (atan (abs bugle)) 4))
  167.          (setq d1   (vlax-curve-getdistAtParam ent n)
  168.          d2   (vlax-curve-getdistAtParam ent (1+ n))
  169.          d   (- d2 d1)
  170.          k   (fix (/ bj fgx))
  171.          d0   (/ 1.0 (1+ k))
  172.          param n
  173.          ) ;_ 结束setq
  174.          (if (equal d0 1.0 0.001)
  175.            (setq plist (cons (vlax-curve-getPointAtParam
  176.              ent
  177.              (+ 0.5 param)
  178.            )
  179.            plist
  180.            )
  181.            )
  182.            (repeat k
  183.        (setq plist (cons (vlax-curve-getPointAtParam
  184.                ent
  185.                (setq param (+ param d0))
  186.              )
  187.              plist
  188.              )
  189.        )
  190.            )
  191.          )
  192.        ) ;_ 结束progn
  193.      ) ;_ 结束if
  194.      )
  195.        )
  196.      (setq n (1+ n))
  197.          ) ;_ 结束repeat
  198.          (if (not (vlax-curve-isClosed ent))
  199.      (setq plist (cons (vlax-curve-getEndPoint ent) plist))
  200.          ) ;_ 结束if
  201.          (reverse plist)
  202.        )
  203.      )
  204.    )
  205.   )
  206.   )
  207. )

  208. (defun gxl-CatchApply ( fun args / result )
  209.   (if
  210.     (not
  211.       (vl-catch-all-error-p
  212.         (setq result
  213.           (vl-catch-all-apply (if (= 'SYM (type fun)) fun (function fun)) args)
  214.         )
  215.       )
  216.     )
  217.     result
  218.   )
  219. )

  220. ;;; Mat:Inverse 求逆矩阵
  221. ;(Mat:Inverse m)
  222. ;;--------------------=={ Inverse Matrix }==------------------;;
  223. ;;                                                            ;;
  224. ;;  Implements the Gauss-Jordan Elimination algorithm to      ;;
  225. ;;  inverse a non-singular nxn matrix.                        ;;
  226. ;;------------------------------------------------------------;;
  227. ;;  Author: Lee Mac, Copyright ? 2011 - www.lee-mac.com       ;;
  228. ;;------------------------------------------------------------;;
  229. ;;  Arguments: m - nxn Matrix                                 ;;
  230. ;;------------------------------------------------------------;;
  231. ;;  Returns:  Matrix inverse, or nil if matrix is singular    ;;
  232. ;;------------------------------------------------------------;;
  233. ;; http://www.theswamp.org/index.php?topic=22638.msg439381#msg439381
  234. (defun Mat:Inverse ( m / _identity _eliminate p r x )
  235.   ;;计算单位矩阵
  236.   (defun _identity ( n / i j l m ) (setq i 1)
  237.     (repeat n (setq j 0)
  238.       (repeat n
  239.         (setq l (cons (if (= i (setq j (1+ j))) 1. 0.) l))
  240.       )
  241.       (setq m (cons l m) l nil i (1+ i)) m
  242.     )
  243.   )

  244.   (defun _eliminate ( m p )
  245.     (mapcar
  246.       (function
  247.         (lambda ( x / d )
  248.           (setq d (car x)) (mapcar (function (lambda ( a b ) (- a (* d b)))) (cdr x) p)
  249.         )
  250.       )
  251.       m
  252.     )
  253.   )
  254.   (setq m (mapcar 'append m (_identity (length m))))
  255.   
  256.   (while m
  257.     (setq p (apply 'max (mapcar 'abs (mapcar 'car m))))
  258.     (while (not (equal p (abs (caar m)) 1e-14))
  259.       (setq m (append (cdr m) (list (car m))))
  260.     )
  261.     (if (equal 0.0 (caar m) 1e-14)
  262.       (setq m nil)
  263.       (setq p (/ 1. (caar m))
  264.             p (mapcar (function (lambda ( x ) (* p x))) (cdar m))
  265.             m (_eliminate (cdr m) p)
  266.             r (cons p (_eliminate r p))
  267.       )
  268.     )
  269.   )
  270.   (reverse r)
  271. )



点评

支持一下  发表于 2015-1-20 14:46

评分

参与人数 3D豆 +20 贡献 +2 收起 理由
Highflybird + 5 + 1 技术引导讨论和指点奖!
XDSoft + 10 + 1 有始有终奖!
Lispboy + 5 很给力!经验;技术要点;资料分享奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 1 反对 0

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-5-24 19:06:38 | 显示全部楼层
牢固 发表于 2013-5-24 10:59
搞清楚了XCLIP剪裁边界的内在机制,下面要重新修改剪裁块的边界就很容易了。我们来看,11楼的代码由剪裁块 ...

精彩的应用,这样做,要比用命令做效率快的多。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-6-3 18:21:48 | 显示全部楼层
好好学习牛人太多了
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

发表于 2013-7-6 15:31:57 | 显示全部楼层
G版研究这么深入,是不是可以写一个完美的局部放大程序了?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2013-9-23 00:12:39 | 显示全部楼层
顶一下。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-1 06:42 , Processed in 0.465969 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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