找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 3223|回复: 3

[教学] 和晓东一起学矩阵(4)比例变换(重写SCALE命令)

[复制链接]

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-5-11 15:07:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
本次教学给大家讲下几何图形矩阵变换中的“比例变换”(SCALE Matrix)

写了两个命令, 等比例变换 mScale 和 不等比例变换 mScale1


数学背景知识:

比例变换-1.png


比例变换-2.png


图形几何变换的详细文章见论文中心:

http://bbs.xdcad.net/plugin.php?id=docswf_wk:wenku_view&docid=43



等比变换命令:

20dbd921c982979c8b3be931c2105bbd.jpg


[pcode=lisp,true];|
   等比缩放
|;
(defun c:mScale( / mat_scl mat0 pj scl ss)
   (if (and (setq ss (ssget))
            (setq pj (getpoint "\n基点<退出>:"))
            (setq scl (getreal "\n比例系数<退出>:"))
       )
     (progn
        (setq mat0 (xdrx_matrix_identity 3))
        (setq mat_scl (xdrx_matrix_setScale mat0 scl pj)) ;;比例变换矩阵
        (xdrx_entity_Transform ss mat_scl)
     )
   )
   (princ)
)[/pcode]

在比例系数1.3,基点是原点(0 0 0)的情况下矩阵是这样的

  1. !mat_scl
  2. ((1.3 0.0 0.0 0.0) (0.0 1.3 0.0 0.0) (0.0 0.0 1.3 0.0) (0.0 0.0 0.0 1.0))

  3. 1.3   0.0   0.0   0.0
  4. 0.0   1.3   0.0   0.0
  5. 0.0   0.0   1.3   0.0
  6. 0.0   0.0   0.0   1.0
复制代码
上面的 xdrx_matrix_setScale 可以根据不同的基点直接生成比例缩放矩阵。如果基点不为原点(0 0 0)的情况下,矩阵又是什么样的呢?如果从数学的分析上怎么得到呢? 这就要分解:

比如基点是P= (2.0 1.5 0.0),那么要围绕P缩放,

1、首先要平移到原点,矩阵m1=

[pcode=lisp,true]
(xdrx_matrix_settranslation mat0 '(-2.0 -1.5 0.0))
;;m1=((1.0 0.0 0.0 -2.0) (0.0 1.0 0.0 -1.5) (0.0 0.0 1.0 0.0) (0.0 0.0 0.0 1.0))
;;1.0 0.0 0.0 -2.0
;;0.0 1.0 0.0 -1.5
;;0.0 0.0 1.0 0.0
;;0.0 0.0 0.0 1.0
[/pcode]
2、绕原点缩放 m2=
[pcode=lisp,true]
(setq mat_scl (xdrx_matrix_setScale mat0 1.3 '(0.0 0.0 0.0)))
((1.3 0.0 0.0 0.0) (0.0 1.3 0.0 0.0) (0.0 0.0 1.3 0.0) (0.0 0.0 0.0 1.0))
;;1.3 0.0 0.0 0.0
;;0.0 1.3 0.0 0.0
;;0.0 0.0 1.3 0.0
; 0.0 0.0 0.0 1.0
[/pcode]
3、在平移回点P, M3=
[pcode=lisp,true]
(xdrx_matrix_settranslation mat0 '(2.0 1.5 0.0))
;;m1=((1.0 0.0 0.0 2.0) (0.0 1.0 0.0 1.5) (0.0 0.0 1.0 0.0) (0.0 0.0 0.0 1.0))
;;1.0 0.0 0.0 2.0
;;0.0 1.0 0.0 1.5
;;0.0 0.0 1.0 0.0
;;0.0 0.0 0.0 1.0
[/pcode]

4、组合起来就是 矩阵相乘, M3  X  M2  X  M1
[pcode=lisp,true]
     ($xdlsp_matrix_product (list m3 m2 m1))
;;((1.3 0.0 0.0 -0.6) (0.0 1.3 0.0 -0.45) (0.0 0.0 1.3 0.0) (0.0 0.0 0.0 1.0))
[/pcode]

[pcode=lisp,true]
(xdrx_matrix_setscale mat0 1.3 '(2.0 1.5 0.0))
((1.3 0.0 0.0 -0.6) (0.0 1.3 0.0 -0.45) (0.0 0.0 1.3 0.0) (0.0 0.0 0.0 1.0))
[/pcode]

分解组合矩阵运算的结果和直接用xdrx_matrix_setscale是一样的。

总结,初等的比例变换矩阵都是基于原点(0 0 0)的,如果基点不在原点,那么要先平移到原点,缩放后,在平移回基点.

二、不等比变换实体能不能实现? (ACAD中只有图块才能不等比例缩放,对一般实体可以不?)
可以,看下面的测试命令:


不等比变换命令:

4fec3e65c6ae12de65759ad23713bc39.jpg


[pcode=lisp,true]
;|
   不等比缩放
|;
(defun c:mScale1( / mat_scl mat0 pj scl_x scl_y ss)
   (if (and (setq ss (ssget))
            (setq pj (getpoint "\n基点<退出>:"))
            (setq scl_x (getreal "\nX比例系数<退出>:"))
            (setq scl_y (getreal "\nY比例系数<退出>:"))
       )
     (progn
        (xdrx_begin)
        (setq mat0 (xdrx_matrix_identity 3))
        (setq mat_scl ($XDLSP_Matrix_SetScale pj (list scl_x scl_y 1.0))) ;;比例变换矩阵
        (xdrx_entity_TransformedCopy ss mat_scl)
        (command ".erase" ss "")
        (xdrx_end)
     )
   )
   (princ)
)

[/pcode]

上面命令涉及到建立不等比例的变换矩阵的函数$XDLSP_Matrix_SetScale:

[pcode=lisp,true]
(defun $XDLSP_Matrix_SetScale (pj scl / mat_t1 mat_t2 mat0 mat2)
  (if (and
        (= 'LIST (type scl))
        (= (length scl) 3)
      )
    (progn
      (setq mat2 (xdrx_matrix_identity 3))
      (setq mat_t1 (xdrx_matrix_settranslation mat2 (mapcar
                                                      '-
                                                      '(0 0 0)
                                                      pj
                                                    )
                   )
            mat_t2 (xdrx_matrix_settranslation mat2 (mapcar
                                                      '-
                                                      pj
                                                      '(0 0 0)
                                                    )
                   )
      )
      (setq mat0 (list (mapcar
                         '*
                         (car mat2)
                         (list (car scl) 0 0 0)
                       ) (mapcar
                           '*
                           (cadr mat2)
                           (list 0 (cadr scl) 0 0)
                         ) (mapcar
                             '*
                             (caddr mat2)
                             (list 0 0 (caddr scl) 0)
                           ) (cadddr mat2)
                 )
      )
      ($xdlsp_matrix_product (list mat_t2 mat0 mat_t1))
    )
  )
)
[/pcode]
[pcode=lisp,true]
;|
矩阵左乘组合函数
(defun $xdlsp_matrix_product (matL / _m1 _m2)
  (if (> (length matl) 1)
    (progn
      (setq _m1 (reverse matL)
            _m2 (car _m1)
      )
      (while (setq _m1 (cdr _m1))
        (setq _m2 (xdrx_matrix_product (car _m1) _m2))
      )
      _m2
    )
  )
)
[/pcode]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2013-5-11 16:32:24 | 显示全部楼层
收藏啦! 有时间好好学习下
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 6468个

财富等级: 富甲天下

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

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-6 00:22 , Processed in 0.193571 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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