尘缘一生 发表于 2024-12-19 18:09:59

关于矩阵的探索之路

本帖最后由 尘缘一生 于 2024-12-19 18:34 编辑

闲来无事,看到本坛的说,COMMANDMOVE   ROTATE
过往啊,我也尝试,探讨许多次,
总觉得,还是COMMAND的快,并不慢,到底怎么快,拿不准主意
鉴于矩阵的话,比较晦涩难懂,弄一段时间,放弃了,
所以啊,高飞大师这种数学好的,是基础科学,好比华为任正非讲的:“俄罗斯科学家那个故事....”
闲也无聊呢,弄几个函数,测试还是不快呢!
难道移动,旋转最快的方式我们找不到吗?特别是和GRREAD整合做起来,频繁刷新时候,能不卡的。
非得C ARX VB去写吗? 可惜我早已忘记C++20几年了,拾不起来!
;实体,选择集,实体表->矩阵移动---(一级)---
(defun sl:move (ss p1 p2)
(sl:mov-ang ss p1 p2 nil)
)
;选择集ss以基点p0 旋转ang(弧度)---(一级)-----
;(sl-rot (ssget) (getpoint) (* pi 0.25))
(defun sl-ssrot (ss p0 ang / mat)
(setq mat (mat:rotation (trans p0 1 0) ang))
(sl:sstransformby mat ss)
(sl-wzgz ss)
(princ)
)
;;实体,选择集,实体表->矩阵从p1到p2移动并旋转ang度-----(一级)------
(defun sl:mov-ang (ss p1 p2 ang / mat)
(if (setq mat (mat:translateby2pang p1 p2 ang))
    (cond
      ((= (type ss) 'ENAME) (vla-transformby (vlax-ename->vla-object ss) (vlax-tmatrix mat))) ;图元
      ((= (type ss) 'PICKSET) (sl:sstransformby mat ss)) ;集
      ((= (type ss) 'LIST) (sl:sstransformby mat (sl:pickset-fromlist ss))) ;实体表
    )
)
)
;平移+旋转变换矩阵---(一级)---
;p1 基点 p2 目标点 并旋转ang(nil 仅平移)度
;(mat:translateby2pang p1 p2 nil) 平移
;(mat:translateby2pang p1 p1 ang) 旋转
;(mat:translateby2pang p1 p2 ang) 平移+旋转
(defun mat:translateby2pang (p1 p2 ang / q mat)
(setq mat (mat:translateby2p p1 p2))
(if ang
    (if mat
      (setq q (mat:rotation (trans p1 1 0) ang) mat (mat:mxm mat q)) ;转动矩阵;矩阵相乘:移动+转动
      (cond
      ((and p1 (is_pt p1))
          (setq mat (mat:rotation (trans p1 1 0) ang))
      )
      ((and p2 (is_pt p2))
          (setq mat (mat:rotation (trans p2 1 0) ang))
      )
      )
    )
)
mat
)
;选择集矩阵变换---(一级)---
(defun sl:sstransformby (mat ss / i e)
(setq mat (vlax-tmatrix mat))
(setq i -1)
(while (setq e (ssname ss (setq i (1+ i))))
    (vla-transformby (vlax-ename->vla-object e) mat)
)
)
;平移变换矩阵---(一级)---
;p1基点 p2目标点
(defun mat:translateby2p (p1 p2 / mat)
(if (and p1 p2 (is_pt p1) (is_pt p2) (> (distance p1 p2) 0.01))
    (setq mat (mat:translation (mapcar '- p2 p1)))
)
mat
)
;平移变换矩阵v 位移矢量---(一级)---
(defun mat:translation (v)
(list
    (list 1. 0. 0. (car v))
    (list 0. 1. 0. (cadr v))
    (list 0. 0. 1. (caddr v))
    (list 0. 0. 0. 1.)
)
)
这一切,只不过是想弄掉几个command代码罢了,举例三领函数之一;然而,效率不行,矩阵再高级,也绝不可入三领集成的。
;SLdesign 三领by 尘缘一生QQ 15290049
;;移动-拷贝-旋转-镜像-递增-放缩------(一级)---------
;;ss:实体、实体表、选择集 p0 移动起点 nil | k: t(move) nil(copy)
(defun sldomov (ss p0 k / e_lst p1 p2 p3 pt pt1 loop ang dis f3 f8 bb p00 a a0 b e1 ee kk px py xx dqxx mk str)
(setq e_lst (sysvar '("QAFLAGS" "CMDECHO" "NOMUTT" "OSMODE" "ORTHOMODE")) p1 (cadr (grread 5)))
(cond
    ((= (type ss) 'ENAME) (setq ss (ssadd ss))) ;图元
    ((= (type ss) 'LIST) (setq ss (sl:pickset-fromlist ss))) ;实体表
)
(command "_.undo" "be") ;;舍弃高级代码,加速
(setvar "CMDECHO" 0) ;;命令显示关闭
(setvar "NOMUTT" 1)
(setvar "QAFLAGS" 0)
(if (= p0 nil)
    (setq p0 (ssmpt ss))
    (setq p0 (polar p1 (angle p1 p0) (distance p1 p0)))
)
(princ
    (setq str
      (slmsg
      "\n->[逆转90度(TAB)/取角(A)/LIN.(E)/<-mir->(D)/↑mir ↓(S)/mir-F(4)/放大(Q)/缩小(W)/递增(Z)/递减(J)/大一倍(+)/小一半(-)/复制当前(C)/基点(X)/正交(F8)/扑捉(F3)](空格..复制)(左键>当前)(右键>退出)"
      "\n->[癴锣90(TAB)/à(A)/LIN.(E)/<-mir->(D)/◆mir □(S)/mir-F(4)/(Q)/罽(W)/患糤(Z)/患搭(J)/(+)/(-)/確讽玡(C)/膀翴(X)/タユ(F8)/汲(F3)](..確)(オ龄>讽玡)(/龄>癶)"
      "\n->Spaced..Copy/Right>Exit"
      )
    )
)
(setq loop t pt1 p0 p2 p0 f8 (getvar "ORTHOMODE") f3 (getvar "OSMODE") dqxx 1)
(while loop
    (setq bb (grread t 15 2) p00 (cadr bb))
    (cond
      ((equal bb '(2 6));F3切换捕捉开关
      (cond
          ((and (< f3 16384) (/= f3 0))
            (setq f3 (+ f3 16384))
            (prompt (slmsg "\n <对象捕捉 关>" "\n <癸禜 闽>" "\n <OSnap Off>"))
          )
          ((or (= f3 0) (>= f3 16384))
            (setq f3 16383)
            (prompt (slmsg "\n <对象捕捉 开>" "\n <癸禜 秨>" "\n <OSnap On>"))
          )
      )
      (setvar "OSMODE" f3) (redraw)
      )   
      ((equal bb '(2 15))    ;F8切换正交开关
      (if (= f8 0)
          (progn (setq f8 1) (prompt (slmsg "\n <正交 开>" "\n <タユ 秨>" "\n <Orth open>")))
          (progn (setq f8 0) (prompt (slmsg "\n <正交 关>" "\n <タユ 闽>" "\n <Orth off>")))
      )
      (setvar "ORTHOMODE" f8) (redraw)
      )
      ((= (car bb) 5)
      (redraw)
      (if (= f8 1)
          (progn
            (setq ang (angle p2 p00))
            (cond
            ((or (and (> ang pi4) (< ang 3pi4)) (and (> ang 5pi4) (< ang 7pi4)))
                (setq pt (list (car p2) (cadr p00)))
            )
            (t
                (setq pt (list (car p00) (cadr p2)))
            )
            )
          )
          (setq pt p00)
      )
      (if (and (<= f3 16384) (> f3 0) (/= f8 1))
          (setq pt (slosnappt ss pt) kk t)
      )
      (if (and (not mk) (> (distance p0 pt) 0.001))
          (command "move" ss "" "_non" p0 "_non" pt)
      )
      (setq p0 pt)
      )
      ((equal bb '(2 52));; 4mir
      (if mk (setq mk nil) (setq mk t p3 nil a0 nil))
      )
      ((member bb '((2 9)))      ;;table 键
      (command "ROTATE" ss "" "_non" pt 90)
      (setq ss (sl-wzgz ss))
      )
      ((member bb '((2 65) (2 97)))   ;;A 旋转定角
      (ss-rotang ss 0) ;选择集先转0度水平
      (setq a (ss9pt ss 1))
      (setq b (polar a 0 500))
      (command ".rotate" ss "" "_non" a "r" "_non" a "_non" (polar pt (angle pt b) (distance pt b)) pause)
      (setq ss (sl-wzgz ss))
      )
      ((member bb '((2 115) (2 83)));;S s 上下翻
      (command "mirror" ss "" "_non" pt "_non" (mapcar '- pt '(1 0)) "Y")
      )
      ((member bb '((2 100) (2 68))) ;;D d 左右翻
      (command "mirror" ss "" "_non" pt "_non" (mapcar '- pt '(0 1)) "Y")
      )
      ((or (member bb '((2 13))) (= (car bb) 3));;左键、回车
      (setq mk nil)
      (if (= k t) ;;移动
          (setq loop nil)
          (progn
            (command "copy" ss "" "_non" '(0 0) "_non" '(0 0))
            (setq ang (angle pt1 pt) dis (distance pt1 pt) pt1 pt)
          )
      )
      )
      ((member bb '((2 69) (2 101)))   ;;E e 齐线
      (princ (slmsg "\n 请选择要对齐的(线或实体)-->" "\n 叫匡拒璶癸霍(絬┪龟砰)-->" "\n Please select the (line or entity) to align -->"))
      (setq ss (ss-rotang ss 0))
      (setq e1 (car (setq ee (entsel ))))
      (setq ang (e-ang e1 (cadr ee)))
      (setq ss (ss-rotang ss ang))
      (setq ss (sl-wzgz ss))
      (princ str)
      )
      ((member bb '((2 67) (2 99)))   ;;C c 复制在当前
      (command "copy" ss "" "_non" '(0 0) "_non" '(0 0))
      (setq ang (angle pt1 pt) dis (distance pt1 pt) pt1 pt)
      )
      ((and (member bb '((2 32))) ang dis) ;;空格键
      (command "copy" ss "" "_non" '(0 0) "_non" '(0 0))
      (command "MOVE" ss "" "_non" pt1 "_non" (setq pt1 (polar pt1 ang dis))) ;;移位
      )
      ((member bb '((2 87) (2 119)))         ;;缩小W w
      (command "scale" ss "" "_non" pt "0.9")
      )
      ((member bb '((2 81) (2 113)))         ;;放大Q q
      (command "scale" ss "" "_non" pt "1.1")
      )
      ((equal bb '(2 45))         ;;缩小一半 -
      (command "scale" ss "" "_non" pt "0.5")
      )
      ((member bb '((2 43) (2 61))) ;;放大一倍 +
      (command "scale" ss "" "_non" pt "2.0")
      )
      ((member bb '((2 90) (2 122)));;递增 Z z
      (setq ss (ss++ ss 1))
      )
      ((member bb '((2 74) (2 106)));;递减 J j
      (setq ss (ss++ ss -1))
      )
      ((member bb '((2 88) (2 120)));;基点 X x
      (command "MOVE" ss "" "_non" pt "_non" p0);;移回去
      (princ (slmsg "\n 指定基点-->" "\n ﹚膀翴-->" "\n Specify Base Point -->"))
      (slslx p0 0)
      (setvar "OSMODE" 16383)
      (setq p1 (getpoint p0))
      (command "MOVE" ss "" "_non" p1 "_non" p0)
      (setvar "OSMODE" f3)
      (princ str)
      )
      ((member (car bb) '(11 25));;右键
      (if (= k t) ;;移动
          (command "MOVE" ss "" "_non" pt "_non" p0);;移回去
          (sl:erase ss)
      )
      (setq loop nil mk nil)
      )
    )
    (if mk
      (progn
      (if (or (not p3) (not a0)) (setq a (ss9pt ss nil) p3 (nth 5 a) a0 (angle (car a) (caddr a))))
      (setq xx (sl-4p p3 p0) px (polar p3 a0 50) py (polar p3 (+ a0 pi2) 50))
      (if (/= dqxx xx)
          (cond
            ((or (= dqxx 1) (= dqxx 4))
            (if (or (= xx 2) (= xx 3)) (command "mirror" ss "" "_non" p3 "_non" py "y"))
            (if (and (/= xx 2) (/= xx 3)) (command "mirror" ss "" "_non" p3 "_non" px "y"))
            )
            ((or (= dqxx 2) (= dqxx 3))
            (if (or (= xx 1) (= xx 4)) (command "mirror" ss "" "_non" p3 "_non" py "y"))
            (if (and (/= xx 1) (/= xx 4)) (command "mirror" ss "" "_non" p3 "_non" px "y"))
            )
          )
      )
      (setq dqxx xx)
      )
    )
);while
(redraw)
(if kk (sl:erase (ssget "X" (list (cons 8 "f-i-n-d")))))
(command "_.undo" "e")
(mapcar 'eval e_lst)
(princ)
)以上函数,我还是采用了COMMAND多,总觉得,还有未知之路,还有永不止境的完善空间......

你有种再说一遍 发表于 2024-12-19 18:23:49

矩阵不难懂,难的是Lisp敲矩阵,
学之前你得知道数组吧,结果你不知道,
数组可以O(1)寻址,结果你不知道,
别人都是有C++经验来教你,
他是降为打击啊,说到降维,
如果连多维数组就是一维数组都不知道,那么就白学了,
一维数组只需要array就是二维数组了,
这样矩阵求值只需要面对一维数组,而不需要考虑多维.
再加强一点,就是CPU预读和硬件加速了.
https://www.cnblogs.com/JJBox/p/14300098.html

尘缘一生 发表于 2024-12-19 18:28:38

本帖最后由 尘缘一生 于 2024-12-19 18:36 编辑

你有种再说一遍 发表于 2024-12-19 18:23
矩阵不难懂,难的是Lisp敲矩阵,
学之前你得知道数组吧,结果你不知道,
数组可以O(1)寻址,结果你不知道,

能不能提速,移动,旋转“大选择集”问题,顾版的哪个函数也是快不起来呢。

你有种再说一遍 发表于 2024-12-19 18:36:59

尘缘一生 发表于 2024-12-19 18:28
能不能提速,移动,旋转“大选择集”问题,顾版的函数也是快不起来呢。

你的这个问题并不用矩阵提速,
这个问题更多是Lisp访问图元之前会进行锁符号表,
这些权限工作会令你大规模操作时候发生瓶颈,
每个图元都锁一次表,和一次锁定再使用,速度就不一样了,
即使同样的代码,在C#敲一遍速度也完全不一样了,
所以想要提速还是要转变一下思维,
尤其是C#有并行,并发,等等许许多多操作.

ddyer 发表于 2024-12-19 18:39:23

每天看会天书,嗯,总有一天会起飞的。

liuhe 发表于 2024-12-20 09:39:41

lsp不适用于追求速度这种,它的特点灵活简单好用,大家学习高级算法,只是便于理解各种底层逻辑。高飞鸟大佬,人家其实玩的是c++,学习矩阵是必须过程

寒潮大冬瓜 发表于 2024-12-21 09:35:56

飞诗的提示
页: [1]
查看完整版本: 关于矩阵的探索之路