关于矩阵的探索之路
本帖最后由 尘缘一生 于 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多,总觉得,还有未知之路,还有永不止境的完善空间......
矩阵不难懂,难的是Lisp敲矩阵,
学之前你得知道数组吧,结果你不知道,
数组可以O(1)寻址,结果你不知道,
别人都是有C++经验来教你,
他是降为打击啊,说到降维,
如果连多维数组就是一维数组都不知道,那么就白学了,
一维数组只需要array就是二维数组了,
这样矩阵求值只需要面对一维数组,而不需要考虑多维.
再加强一点,就是CPU预读和硬件加速了.
https://www.cnblogs.com/JJBox/p/14300098.html 本帖最后由 尘缘一生 于 2024-12-19 18:36 编辑
你有种再说一遍 发表于 2024-12-19 18:23
矩阵不难懂,难的是Lisp敲矩阵,
学之前你得知道数组吧,结果你不知道,
数组可以O(1)寻址,结果你不知道,
能不能提速,移动,旋转“大选择集”问题,顾版的哪个函数也是快不起来呢。 尘缘一生 发表于 2024-12-19 18:28
能不能提速,移动,旋转“大选择集”问题,顾版的函数也是快不起来呢。
你的这个问题并不用矩阵提速,
这个问题更多是Lisp访问图元之前会进行锁符号表,
这些权限工作会令你大规模操作时候发生瓶颈,
每个图元都锁一次表,和一次锁定再使用,速度就不一样了,
即使同样的代码,在C#敲一遍速度也完全不一样了,
所以想要提速还是要转变一下思维,
尤其是C#有并行,并发,等等许许多多操作. 每天看会天书,嗯,总有一天会起飞的。 lsp不适用于追求速度这种,它的特点灵活简单好用,大家学习高级算法,只是便于理解各种底层逻辑。高飞鸟大佬,人家其实玩的是c++,学习矩阵是必须过程 飞诗的提示
页:
[1]