**任意轴算法**
官方文档 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)
**测试通过**
- 前言
- 概述
- autolisp简介(初)
- 搭建编程环境
- Visual Lisp 编辑器的使用(初)
- vs code的使用
- 基本概念(初)
- 表达式
- 数据类型
- 整数类型
- 实数类型
- 字符串类型
- 列表
- 选择集类型
- 实体名称(ename)
- vla对象(vla-object)
- 文件描述符
- 符号和变量(初)(精)
- 源码文件
- 变量
- 变量的类型
- 变量赋值
- 变量求值
- 预定义变量
- 数值处理
- 字符串处理
- 显示和输出
- 控制字符
- 列表操作
- 重点函数列表
- 尺寸标注
- 文字固定偏移
- 填充
- 填充到指定的矩形
- 计算填充面积并标注
- 其他
- 绘制任意曲线的等分线
- 原位缩放
- 修改填充基点和角度
- 批量标注多段线长度
- 统计相同直径的圆的数量
- z坐标置0
- 生成随机数
- 图层
- 相交
- intersectWith无法求交点的几种情形
- 向量和矩阵
- 向量加减乘除
- 向量长度
- 求单位向量
- 向量点积
- 向量叉积
- 命令和交互
- 调用command命令
- 多段线
- 获取多段线顶点
- UCS
- 有关ucs的命令和系统变量
- 通过command操作ucs
- 草图设置
- 捕捉
- 栅格
- 正交
- 对象捕捉
- 坐标系和变换(高级)
- 任意轴算法
- 坐标系
- trans
- geomcal
- autocad开发相关网站
- 小技巧汇总
- 判断点是否在封闭图形内
- 安装
- acad启动加载顺序
- 安装包制作
- 添加文件到启动组
- 添加目录到搜索路径
- 对话框和图形界面
- DCL
- openDCL
- 菜单和自定义界面
- 菜单文件
- 自定义文件
- 函数参考
- quote