ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
**任意轴算法** 官方文档 https://help.autodesk.com/view/OARX/2019/ENU/?guid=GUID-E19E5B42-0CC7-4EBA-B29F-5E1D595149EE 其大体意思是说: 任意轴算法 被用于在autocad程序内部,用来产生对象坐标系(ocs)的。 给定一个单位向量,任意轴算法可以生成一个坐标系。 算法具体如下:(所有向量位于三维空间,用世界坐标表示) N--给定的单位向量 Nx--N的x轴分量 Ny--N的y轴分量 Wy--世界坐标系的y轴方向向量,当然是(0,1,0) Wz--世界坐标系的z轴方向向量,当然是(0,0,1) Ax--新坐标系的x轴向量 Ay--新坐标系的y轴向量 Az--新坐标系的z轴向量 ~~~ 新坐标系原点为(0,0,0) Az=N If (abs (Nx) < 1/64) and (abs (Ny) < 1/64) then Ax = Wy X N ( “X” 表示向量叉乘). Otherwise, Ax = Wz X N. 将 Ax 规范化为单位向量. Ay = N X Ax. 将 Ay 规范化为单位向量 ~~~ 任意轴算法的lisp实现 ``` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;任意轴算法的lisp实现,来自http://bbs.mjtd.com/forum.php?mod=viewthread&tid=99954&highlight=trans ;;OCS的变换矩阵,或叫法线矢量的变换矩阵 (defun OcsMatrix (zdir / xdir) (or (equal 1.0 (distance '(0 0 0) zdir) 1e-8) (setq zdir (Normalize zdir)) ; 先把矢量单位化。 ) (if (and (< (abs (car zdir)) 0.015625) ; 如果(abs (Nx) < 1/64) (< (abs (cadr zdir)) 0.015625) ; 且 (abs (Ny) < 1/64) ) (setq xdir (Normalize (CrossProduct '(0 1 0) zdir))); Ax = Wy X N (叉积) (setq xdir (Normalize (CrossProduct '(0 0 1) zdir)));否则 Ax = Wz X N。 ) (list xdir (Normalize (CrossProduct zdir xdir)) zdir) ;Y方向满足右手型坐标系统 ) ;; 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) ) ) ;; Apply a transformation matrix to a vector by Vladimir Nesterovsky (defun mxv (m v) (mapcar (function (lambda (r) (apply '+ (mapcar '\* r v)))) m) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ``` 验证上述算法的正确性 思路:给定一个向量normal,用任意轴算法生成normal对应的坐标系cs1 用trans函数 将任意点,从normal对应的ocs(通过系统的任意轴算法生成)变换到cs1,如果点坐标没有变化,说明 normal对应的ocs和任意轴算法给出的cs1是相同的,也就说明我们的任意轴算法和系统的任意轴算法是功能一致的。 验证用到的函数 ``` ;;;;;;;;;;;;;;;;;;;;;;; ;by 鸟哥qq1833183060 ;验证任意轴算法 OcsMatrix 的正确性 ;normal 为任意向量 (defun OcsMatrix-test (normal / ent ocsvector) (setq oldosmode (getvar "osmode")) (setvar "osmode" (logior (getvar "osmode") 16384)) (setq pt (list 1 1 1)) (command "ucs" "") (setq ocsvector (OcsMatrix normal)) (princ ocsvector) (command "ucs" "3p" "0,0,0" (car ocsvector) (cadr ocsvector) ) (setq pt2 (trans '(0 0 1) normal 1)) (princ "\\n(0 0 1)变换后坐标是:") (princ pt2) (setq pt2 (trans '(1 0 0) normal 1)) (princ "\\n(1 0 0)变换后坐标是:") (princ pt2) (setq pt2 (trans '(0 1 0) normal 1)) (princ "\\n(0 1 0)变换后坐标是:") (princ pt2) (setvar "osmode" oldosmode) (princ) ) ``` 执行:(ocsmatrix-test (list 20 33 880)) 结果: (0 0 1)变换后坐标是:(7.70372e-034 1.38778e-017 1.0) (1 0 0)变换后坐标是:(1.0 -5.55112e-017 3.46945e-018) (0 1 0)变换后坐标是:(5.55112e-017 1.0 -6.93889e-018) 执行:(ocsmatrix-test (list 20 303 880)) 结果: (0 0 1)变换后坐标是:(-3.46945e-018 5.55112e-017 1.0) (1 0 0)变换后坐标是:(1.0 0.0 -3.46945e-018) (0 1 0)变换后坐标是:(0.0 1.0 -5.55112e-017) 执行:(ocsmatrix-test (list 20 0 880)) 结果: (0 0 1)变换后坐标是:(0.0 0.0 1.0) (1 0 0)变换后坐标是:(1.0 0.0 0.0) (0 1 0)变换后坐标是:(0.0 1.0 0.0) **测试通过**