假设一个法线矢量为'(1 2 4)把这个矢量化为单位矢量 得到ZDir : '(0.218218 0.436436 0.872872)
因为这个矢量 的x 和y 数值都大于0.015625,就用 ‘(0 0 1) 跟 '(0.218218 0.436436 0.872872) 叉积,
否则要用 '(0 1 0)跟它叉积。 这样结果是: ‘(-0.436436 0.218218 0.0) ,把这个再单位矢量化,
得到XDir : (-0.894427 0.447214 0.0)
用ZDir跟XDir 叉积,得到 '(-0.39036 -0.78072 0.48795) ,再把这个单位矢量化(可以省略这一步的)
得到YDir ‘(-0.39036 -0.78072 0.48795) ,因而,得到变换矩阵为为:
( (-0.894427 0.447214 0.0)
(-0.39036 -0.78072 0.48795)
(0.218218 0.436436 0.872872)
)
这个就是变换矩阵.
- 以下为LISP代码:
- ;;;example : (OcsMatrix '(1 2 4))
- ;;; OcsMatrix
- ;;; Returns the OCS 3x3 matrix (X, Y, Z vectors) from an 'extrusion vector' (zdir)
- ;;; the matrix is calculated with the arbitrary axis algorythm.
- ;;
- ;; Argument : the 'extrusion direction' vector
- (defun OcsMatrix (zdir / xdir)
- (or (= 1.0 (distance '(0 0 0) zdir))
- (setq zdir (Normalize zdir))
- )
- (if (and (< (abs (car zdir)) 0.015625)
- (< (abs (cadr zdir)) 0.015625)
- )
- (setq xdir (Normalize (CrossProduct '(0 1 0) zdir)))
- (setq xdir (Normalize (CrossProduct '(0 0 1) zdir)))
- )
- (list xdir (Normalize (CrossProduct zdir xdir)) zdir)
- )
- ;; CrossProduct
- ;; Returns the cross product (vector) of two vectors
- ;;
- ;; Arguments : two vectors
- (defun CrossProduct (v1 v2)
- (list (- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2)))
- (- (* (caddr v1) (car v2)) (* (car v1) (caddr v2)))
- (- (* (car v1) (cadr v2)) (* (cadr v1) (car v2)))
- )
- )
- ;; Normalize
- ;; Returns the single unit vector
- ;;
- ;; Argument : a vector
- (defun Normalize (v)
- ((lambda (l)
- (if (/= 0 l)
- (mapcar (function (lambda (x) (/ x l))) v)
- )
- )
- (distance '(0 0 0) v)
- )
- )
|