明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2162|回复: 9

[经验] 对块中对象利用nentsel返回的转换矩阵进行坐标转换的方法

[复制链接]
发表于 2018-4-4 22:37 | 显示全部楼层 |阅读模式
块中对象,如多段线的坐标需要通过函数转换才能变回世界坐标。具体方法是坐标乘以nentsel返回的第三项转换矩阵得到,但搜了一下,一时半会儿没搜到,自己写了一个,供需要的朋友使用。
  1. ;;说明:利用nentsel的第三项转换矩阵对点表进行转换
  2. ;;参数:pts:多段线点表,应为三维
  3. ;;参数:m:转换矩阵
  4. ;;返回:转换后的点表
  5. ;;调试:
  6. ;;(setq aa1 (nentsel->wcs '((0.0 0.0 0.0) (3240.92 0.0 0.0) (3240.92 -3652.84 0.0) (0.0 -3652.84 0.0)) (caddr (setq entt (nentsel)))))
  7. (defun nentsel->wcs (pts m / )
  8.   (setq pts (mapcar '(lambda (x) (conslast 1.0 x)) pts))
  9.   (mapcar '(lambda (x) (zrmat:vxm x m)) pts)
  10. )
  11. ;;以下为子函数
  12. ;;;
  13. ;;在表的末尾加个元素
  14. (defun conslast (x l / )
  15.   (reverse (cons x (reverse l)))
  16. )
  17. ;;向量乘以矩阵
  18. (defun zrmat:vxm (v m / i sum)
  19.   (setq i 1 sum nil)
  20.   (repeat (zrmat:m-col-len m)
  21.     (setq sum (cons (zrmat:vxu v (zrmat:m-col-index m i)) sum))
  22.     (setq i (1+ i))
  23.   )
  24.   (reverse sum)
  25. )
  26. ;;获取矩阵的列数
  27. (defun zrmat:m-col-len (m / )
  28.   (apply 'max (mapcar 'length m))
  29. )
  30. ;;向量乘以向量
  31. (defun zrmat:vxu (v u / )
  32.   (apply '+ (mapcar '(lambda (x y) (* x y)) u v))
  33. )
  34. ;;获取矩阵的某一列
  35. (defun zrmat:m-col-index (m col-index / )
  36.   (if (and (> col-index 0) (<= col-index (zrmat:m-col-len m)))
  37.     (mapcar '(lambda (x) (nth (1- col-index) x)) m)
  38.   )
  39. )


注1:按道理说,这个功能应该有人实现了能搜到才对,我怎么没搜到?搜索能力不行?望各位指导!
注2:子函数写得有点繁琐,感觉完全可以精简才对。

------分割线------
为便于调试,放一个获取多段线坐标的函数,供需要的朋友使用:
  1. ;获取多段线坐标,输入一个pl-en,和返回点的维数信息,返回wcs下的pl坐标
  2. ;(pl->pts (car(nentsel)) 2)
  3. ;(pl->pts (car(nentsel)) 3)
  4. ;;说明:获取多段线坐标
  5. ;;参数:pl:一个多段线的en对象
  6. ;;参数:num:2 或者 3,当为3时,返回带z坐标的三维点
  7. ;;返回:多段线的端点列表
  8. (defun pl->pts (pl num / pts z)
  9.   (setq pts (vl-remove-if-not '(lambda (x) (= 10 (car x))) (entget pl)))
  10.   (setq pts (mapcar 'cdr pts))
  11.   (if (= num 3) (setq pts (mapcar '(lambda (x) (conslast (if (setq z (assoc 38 (entget pl))) (cdr z) 0.0) x)) pts)))
  12.   pts
  13. )


发表于 2018-4-5 10:45 | 显示全部楼层
不错,学习了,谢谢楼主分享!
发表于 2018-4-5 13:39 | 显示全部楼层
非常给力,但不知楼主实际的应用场合
 楼主| 发表于 2018-4-5 17:00 | 显示全部楼层
renhaitao_nice 发表于 2018-4-5 13:39
非常给力,但不知楼主实际的应用场合

比如获取块中多段线的坐标。如果直接获取,比如用entge nentsel方法或者get-coordinates等,获取的坐标都是相对块的,不是世界坐标或用户左边,需要转换一次。此处给出的就是转换方法。
发表于 2018-4-8 10:11 | 显示全部楼层

(defun MAT:mxv (m v)
  (mapcar (function (lambda (r) (apply '+ (mapcar '* r v)))) m)
)

(defun MAT:mxp (m p)
  (reverse (cdr (reverse (MAT:mxv m (append p '(1.0))))))
)

(defun nentsel->wcs (matrix pts)
  (mapcar '(lambda (x) (MAT:mxp matrix x)) pts)
)

这类的问题查找一下高飞鸟版主贴子
发表于 2018-4-11 08:36 | 显示全部楼层
去搜下langjs的相同刷,上面好像有nentsel的转换,直接用的trans。
http://bbs.mjtd.com/thread-101921-1-1.html
 楼主| 发表于 2018-4-14 19:10 | 显示全部楼层
pzweng 发表于 2018-4-8 10:11
(defun MAT:mxv (m v)
  (mapcar (function (lambda (r) (apply '+ (mapcar '* r v)))) m)
)

谢谢。但直接搜索nentsel或者nentsel->wcs,都搜不到相关的内容。只能进到帖子里再找吗?
发表于 2018-8-30 17:01 来自手机 | 显示全部楼层
如果要循环很多块,每个块里面都有嵌套块,我的问题是 有什么办法在不用nentsel函数(因为它必须点选,而循环没法点选)的方式下获得嵌套块的插入点坐标(这个坐标我能得到,但是是模型空间里的OCS坐标)的模型空间转世界空间的转换矩阵?谢谢知道的大神点拨一下!
发表于 2018-11-25 19:11 | 显示全部楼层
trans点坐标,从一个坐标系  转换到另一个坐标系,多层镶套块比较麻烦。
发表于 2018-12-7 21:01 来自手机 | 显示全部楼层
jin1114 发表于 2018-8-30 17:01
如果要循环很多块,每个块里面都有嵌套块,我的问题是 有什么办法在不用nentsel函数(因为它必须点选,而循 ...

不手动选点就用nentselp函数。多层嵌套的块用递归方法应该可以,我用到的几个递归函数都是用在嵌套块上的。递归的好处是不管块的嵌套层数是多少都没问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-19 13:53 , Processed in 0.152427 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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