- 积分
- 39619
- 明经币
- 个
- 注册时间
- 2006-8-18
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 highflybir 于 2013-1-9 12:51 编辑
用LISP论矩阵
矩阵的LISP程序,国内讨论的比较少, 而国外的研究比较深入。
经过长时间的收藏和探索,我综合成了这篇帖子。
这个帖子里面的函数主要是跟CAD 相关。附件包含了本帖完整的lisp代码,还有测试样例。
是一个比较完整的矩阵库。
另外,本帖附上了一些矩阵相关链接。 错误和纰漏之处请大家多多指教。
样例及演示可以参考12楼,另外附件中也有样例。
一、向量的运算
向量,矩阵是息息相关的。这里列出了向量的一些基本运算。 - ;;;-----------------------------------------------------------;;
- ;;; 两向量相加 addition ;;
- ;;; Input: v1,v2 -vectors in R^n ;;
- ;;; OutPut: A vector ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:v+v (v1 v2)
- (mapcar '+ v1 v2)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 两向量相减 subtraction ;;
- ;;; Input: v1,v2 -vectors in R^n ;;
- ;;; OutPut: A vector ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:v-v (v1 v2)
- (mapcar '- v1 v2)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 两向量相乘 multiplication ;;
- ;;; Input: v1,v2 -vectors in R^n ;;
- ;;; OutPut: A vector ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:v*v (v1 v2)
- (mapcar '* v1 v2)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 两向量相除 division ;;
- ;;; Input: v1,v2 -vectors in R^n ;;
- ;;; OutPut: A vector ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:v/v (v1 v2)
- (mapcar '/ v1 v2)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 向量乘标量(系数) ;;
- ;;; Vector x Scalar - Lee Mac ;;
- ;;; Args: v - vector in R^n, s - real scalar ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:vxs ( v s )
- (mapcar (function (lambda ( n ) (* n s))) v)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 两向量的点积 ;;
- ;;; Vector Dot Product ;;
- ;;; Input: v1,v2 -vectors in R^n ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Dot (v1 v2)
- (apply '+ (mapcar '* v1 v2))
- )
- ;;;-----------------------------------------------------------;;
- ;;; 两向量的叉积 ;;
- ;;; Vector Cross Product ;;
- ;;; Args: u,v - vectors in R^3 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:vxv ( u v )
- (list
- (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
- (- (* (car v) (caddr u)) (* (car u) (caddr v)))
- (- (* (car u) (cadr v)) (* (car v) (cadr u)))
- )
- )
- ;;;-----------------------------------------------------------;;
- ;;; 线性组合 标量组乘向量组 ;;
- ;;; Linear combination - highflybird ;;
- ;;; Input: Vectors - vectors, Scalars, - a real number list ;;
- ;;; Output: a vector ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:SxVs (Vectors Scalars)
- (apply 'mapcar (cons '+ (mapcar 'MAT:vxs Vectors Scalars)))
- )
- ;;;-----------------------------------------------------------;;
- ;;; 向量的模(长度) ;;
- ;;; Vector Norm - Lee Mac ;;
- ;;; Args: v - vector in R^n ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:norm ( v )
- (sqrt (apply '+ (mapcar '* v v)))
- )
- ;;;-----------------------------------------------------------;;
- ;;; 向量的模(长度) ;;
- ;;; Vector Norm - highflybird ;;
- ;;; Args: v - vector in R^3 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Norm3D ( v )
- (distance '(0 0 0) v)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 单位向量 ;;
- ;;; Unit Vector - Lee Mac ;;
- ;;; Args: v - vector in R^n ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Unitization (v)
- ( (lambda (n)
- (if (equal 0.0 n 1e-14)
- nil
- (MAT:vxs v (/ 1.0 n))
- )
- )
- (MAT:norm v)
- )
- )
- ;;;-----------------------------------------------------------;;
- ;;; 单位向量 ;;
- ;;; Unit Vector - highflybird ;;
- ;;; Args: v - vector in R^3 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:unit ( v / l)
- (cond
- ( (= (setq l (MAT:Norm3D v)) 1.0 ) v)
- ( (> l 1e-14) (MAT:vxs v (/ 1.0 l)))
- )
- )
- ;;;-----------------------------------------------------------;;
- ;;; 两个2d向量的叉积的数值 ;;
- ;;; 输入: 两个点(或者两个向量) ;;
- ;;; 输出: 一个数值.如果为正则是逆时针,两向量形成的平面法线向量;;
- ;;; 向上,为负则是顺时针,为零则两向量共线或平行。 ;;
- ;;; 这个数值也为原点,P1,P2三点面积的两倍。 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Det2V (v1 v2)
- (- (* (car v1) (cadr v2)) (* (car v2) (cadr v1)))
- )
二、向量的旋转- ;;;-----------------------------------------------------------;;
- ;;; 旋转一个向量或者点90度 ;;
- ;;; 输入: 一个向量 ;;
- ;;; 输出: 被旋转90度后的向量 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Rot90 (vec)
- (vl-list* (- (cadr vec)) (car vec) (cddr vec))
- )
- ;;;-----------------------------------------------------------;;
- ;;; 旋转向量到指定角度 ;;
- ;;; 输入: 一个向量和指定的角度 ;;
- ;;; 输出: 被旋转后的向量 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Rot2D (v a / c s x y)
- (setq c (cos a) s (sin a))
- (setq x (car v) y (cadr v))
- (list (- (* x c) (* y s)) (+ (* x s) (* y c)))
- )
三、 行列式
这里只讨论二阶和三阶的行列式 - ;;;-----------------------------------------------------------;;
- ;;; 2d行列式 determinant in R^2 ;;
- ;;; Args: 4 numbers ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Det2 (x1 y1 x2 y2)
- (- (* x1 y2) (* x2 y1))
- )
- ;;;-----------------------------------------------------------;;
- ;;; 3d行列式 determinant in R^3 ;;
- ;;; Args: 9 numbers ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Det3 (a1 b1 c1 a2 b2 c2 a3 b3 c3)
- (+ (* a1 (- (* b2 c3) (* b3 c2)))
- (* a2 (- (* b3 c1) (* b1 c3)))
- (* a3 (- (* b1 c2) (* b2 c1)))
- )
- )
四、 矩阵的基本运算- ;;;-----------------------------------------------------------;;
- ;;; 矩阵转置 ;;
- ;;; MAT:trp Transpose a matrix -Doug Wilson- ;;
- ;;; 输入:矩阵 ;;
- ;;; 输出:转置后的矩阵 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:trp (m)
- (apply 'mapcar (cons 'list m))
- )
- ;;;-----------------------------------------------------------;;
- ;;; 矩阵相加 ;;
- ;;; Matrix + Matrix - Lee Mac ;;
- ;;; Args: m,n - nxn matrices ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:m+m ( m n )
- (mapcar '(lambda ( r s ) (mapcar '+ r s)) m n)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 矩阵相减 ;;
- ;;; Matrix - Matrix - Lee Mac ;;
- ;;; Args: m,n - nxn matrices ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:m-m ( m n )
- (mapcar '(lambda ( r s ) (mapcar '- r s)) m n)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 矩阵相乘 ;;
- ;;; MAT:mxm Multiply two matrices -Vladimir Nesterovsky- ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:mxm (m q)
- (mapcar (function (lambda (r) (MAT:mxv (MAT:trp q) r))) m)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 矩阵乘标量 ;;
- ;;; Matrix x Scalar - Lee Mac ;;
- ;;; Args: m - nxn matrix, n - real scalar ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:mxs ( m s )
- (mapcar (function (lambda ( v )(MAT:VxS v s))) m)
- )
五、 矩阵与向量的运算- ;;;-----------------------------------------------------------;;
- ;;; 向量或点的矩阵变换(向量乘矩阵) ;;
- ;;; Matrix x Vector - Vladimir Nesterovsky ;;
- ;;; Args: m - nxn matrix, v - vector in R^n ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:mxv (m v)
- (mapcar (function (lambda (r) (apply '+ (mapcar '* r v)))) m)
- )
- ;;;-----------------------------------------------------------;;
- ;;; 点的矩阵(4x4 matrix) 变换 ;;
- ;;; 输入:矩阵m和一个三维点p ;;
- ;;; 输出:点变换后的位置 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:mxp (m p)
- (reverse (cdr (reverse (MAT:mxv m (append p '(1.0))))))
- )
-
六、矩阵的平面和空间变换
以下是一些矩阵变换的函数。
二维镜像变换- ;;;-----------------------------------------------------------;;
- ;;; 二维镜像变换矩阵 ;;
- ;;; 参数: ;;
- ;;; p1 - 镜像向量第一点 ;;
- ;;; p2 - 镜像向量第二点 ;;
- ;;;-----------------------------------------------------------;;
- ;;;----------------=={ Reflect by Matrix }==------------------;;
- ;;; ;;
- ;;; Reflects a VLA-Object or Point List using a ;;
- ;;; Transformation Matrix ;;
- ;;;-----------------------------------------------------------;;
- ;;; Author: Lee Mac, Copyright ? 2010 - www.lee-mac.com ;;
- ;;;-----------------------------------------------------------;;
- ;;; Arguments: ;;
- ;;; target - VLA-Object or Point List to transform ;;
- ;;; p1, p2 - Points representing vector in which to reflect ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Reflect ( p1 p2 / a c s x y)
- (setq a (angle p1 p2) a (+ a a))
- (setq c (cos a) s (sin a))
- (setq x (car p1) y (cadr p1))
- (list
- (list c s 0. (- x (+ (* c x) (* s y))))
- (list s (- c) 0. (- y (- (* s x) (* c y))))
- '(0. 0. 1. 0.)
- '(0. 0. 0. 1.)
- )
- )
三维镜像变换- ;;;-----------------------------------------------------------;;
- ;;; 三维镜像变换矩阵 ;;
- ;;; 参数: ;;
- ;;; p1,p2,p3 - 三点定义的镜像平面 ;;
- ;;;-----------------------------------------------------------;;
- ;;;---------------=={ 3D Reflect by Matrix }==----------------;;
- ;;; ;;
- ;;; Reflection matrix ;;
- ;;;-----------------------------------------------------------;;
- ;;; Author: highflybird, Copyright ? 2012- ;;
- ;;;-----------------------------------------------------------;;
- ;;; Arguments: ;;
- ;;; p1,p2,p3 - Three 3D points defining the reflection plane ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:Reflect3D (p1 p2 p3 / m ux uy uz)
- (mapcar
- 'set
- '(ux uy uz)
- (MAT:unit (MAT:vxv (mapcar '- p2 p1) (mapcar '- p3 p1)))
- )
- (setq m (list (list (- 1. (* 2. ux ux)) (* -2. uy ux) (* -2. ux uz))
- (list (* -2. ux uy) (- 1. (* 2. uy uy)) (* -2. uy uz))
- (list (* -2. ux uz) (* -2. uy uz) (- 1. (* 2. uz uz)))
- )
- )
- (Mat:DispToMatrix m (mapcar '- p1 (MAT:mxv m p1)))
- )
附件中包含Lee-mac的一些算法,与我的大同小异。区别在于,我的矩阵是为大量运算准备,
Lee-mac的为单次次数不多时运用。
七、块参照,属性的变换矩阵和逆矩阵
附件 - ;;;-----------------------------------------------------------;;
- ;;; 功能: 某点在块内坐标系统和世界或者用户坐标系统的转换 ;;
- ;;; 参数: pt 要变换的点。 ;;
- ;;; rlst 用 nentselp或者nentsel得到的表的最后一项 ;;
- ;;; from 坐标系:0,WCS; 1,当前UCS; 2,块参照坐标系RCS ;;
- ;;; to 坐标系:0,WCS; 1,当前UCS; 2,块参照坐标系RCS ;;
- ;;;-----------------------------------------------------------;;
- ;;; MAT:TransNested (gile) ;;
- ;;; Translates a point coordinates from WCS or UCS to RCS ;;
- ;;; -coordinates system of a ;;
- ;;; reference (xref or block) whatever its nested level- ;;
- ;;; ;;
- ;;; Arguments ;;
- ;;; pt : the point to translate ;;
- ;;; rlst : the parents entities list from the deepest nested ;;
- ;;; to the one inserted in current space -same as ;;
- ;;; (last (nentsel)) or (last (nentselp)) ;;
- ;;; from to : as with trans function: 0.WCS, 1.UCS, 2.RCS ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:TransNested (pt rlst from to / GEOM)
- (and (= 1 from) (setq pt (trans pt 1 0)))
- (and (= 2 to) (setq rlst (reverse rlst)))
- (and (or (= 2 from) (= 2 to))
- (while rlst
- (setq geom (if (= 2 to)
- (MAT:RevRefGeom (car rlst))
- (MAT:RefGeom (car rlst))
- )
- rlst (cdr rlst)
- pt (mapcar '+ (MAT:mxv (car geom) pt) (cadr geom))
- )
- )
- )
- (if (= 1 to)
- (trans pt 0 1)
- pt
- )
- )
- ;;;-----------------------------------------------------------;;
- ;;; 功能:图块的变换矩阵 ;;
- ;;; 输入:块参照的图元名 ;;
- ;;; 输出:块参照的变换矩阵 ;;
- ;;;-----------------------------------------------------------;;
- ;;; MAT:RefGeom (gile) ;;
- ;;; Returns a list which first item is a 3x3 transformation ;;
- ;;; matrix(rotation,scales normal) and second item the object ;;
- ;;; insertion point in its parent(xref, bloc or space) ;;
- ;;; ;;
- ;;; Argument : an ename ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:RefGeom (ename / elst ang norm mat)
- (setq elst (entget ename)
- ang (cdr (assoc 50 elst))
- norm (cdr (assoc 210 elst))
- )
- (list
- (setq mat
- (MAT:mxm
- (mapcar (function (lambda (v) (trans v 0 norm T)))
- '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
- )
- (MAT:mxm
- (list (list (cos ang) (- (sin ang)) 0.0)
- (list (sin ang) (cos ang) 0.0)
- '(0.0 0.0 1.0)
- )
- (list (list (cdr (assoc 41 elst)) 0.0 0.0)
- (list 0.0 (cdr (assoc 42 elst)) 0.0)
- (list 0.0 0.0 (cdr (assoc 43 elst)))
- )
- )
- )
- )
- (mapcar
- '-
- (trans (cdr (assoc 10 elst)) norm 0)
- (MAT:mxv mat
- (cdr (assoc 10 (tblsearch "BLOCK" (cdr (assoc 2 elst)))))
- )
- )
- )
- )
- ;;;-----------------------------------------------------------;;
- ;;; 功能:图块的变换矩阵的逆矩阵 ;;
- ;;;-----------------------------------------------------------;;
- ;;; MAT:RevRefGeom (gile) ;;
- ;;; MAT:RefGeom inverse function ;;
- ;;; 输入:块参照的图元名 ;;
- ;;; 输出:块参照的变换矩阵的逆矩阵 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:RevRefGeom (ename / entData ang norm mat)
- (setq entData (entget ename)
- ang (- (cdr (assoc 50 entData)))
- norm (cdr (assoc 210 entData))
- )
- (list
- (setq mat
- (MAT:mxm
- (list (list (/ 1 (cdr (assoc 41 entData))) 0.0 0.0)
- (list 0.0 (/ 1 (cdr (assoc 42 entData))) 0.0)
- (list 0.0 0.0 (/ 1 (cdr (assoc 43 entData))))
- )
- (MAT:mxm
- (list (list (cos ang) (- (sin ang)) 0.0)
- (list (sin ang) (cos ang) 0.0)
- '(0.0 0.0 1.0)
- )
- (mapcar (function (lambda (v) (trans v norm 0 T)))
- '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
- )
- )
- )
- )
- (mapcar '-
- (cdr (assoc 10 (tblsearch "BLOCK" (cdr (assoc 2 entData)))))
- (MAT:mxv mat (trans (cdr (assoc 10 entData)) norm 0))
- )
- )
- )
- ;;;-----------------------------------------------------------;;
- ;;; 属性的变换矩阵Attrib Transformation Matrix. -highflybird ;;
- ;;; 输入:Ename 属性的图元名 ;;
- ;;; 输出:属性的变换矩阵 ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:AttGeom (ename / ang norm mat elst)
- (setq elst (entget ename)
- ang (cdr (assoc 50 elst))
- norm (cdr (assoc 210 elst))
- )
- (list
- (setq mat
- (mxm
- (mapcar (function (lambda (v) (trans v 0 norm T)))
- '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
- )
- (list (list (cos ang) (- (sin ang)) 0.0)
- (list (sin ang) (cos ang) 0.0)
- '(0.0 0.0 1.0)
- )
- )
- )
- (trans (cdr (assoc 10 elst)) norm 0)
- )
- )
八、三点变换矩阵,UCS变换矩阵,图元变换矩阵和通用变换矩阵
九、轴测变换矩阵- ;;;-----------------------------------------------------------;;
- ;;;通用的轴测变换矩阵 highflybird 2012.12 ;;
- ;;;Axonometric projections Rotation matrices ;;
- ;;;Isometric projection: a = (/ pi 4),b = (atan (- (sqrt 2))) ;;
- ;;;Input: a - Rotation angle about the vertical axis ;;
- ;;; b - Rotation angle about the horizontal axis ;;
- ;;;Output: transforamtion matrix of this projection ;;
- ;;;-----------------------------------------------------------;;
- (defun MAT:ISO (a b / ca sa cb sb)
- (setq ca (cos a))
- (setq sa (sin a))
- (setq cb (cos b))
- (setq sb (sin b))
- (list (list ca (- sa) 0 0)
- (list (* sa cb) (* ca cb) (- sb) 0)
- (list (* sa sb) (* ca sb) cb 0)
- (list 0 0 0 1)
- )
- )
演示: 关于上面的几个链接地址的源代码已经录入下面的附件中了。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
评分
-
查看全部评分
"觉得好,就打赏"
共1人打赏
|