DTranform3d和DMatrix理解
DTransform3d 是 Bentley 中几何变换的类,通过它可以快速生成变换矩阵。
程序集 | 命名空间 |
---|---|
Bentley.GeometryNET.Structs.dll | Bentley.GeometryNET |
DPoint3d
代表点,点也可以看成是从原点开始的向量
DVector3d
代表向量
DMatrix
它的类型的是 Struct,代表方阵,有 DMatrix2d、DMatrix3d、DMatrix4d,是基本的数学几何表达。
DTransform3d
DTransform3d 是齐次表达式型矩阵的一种封装,有 DTransform2d 和 DTransform3d,分别代表 2x3 和 3x4 阶矩阵。
它内部的一些变换使用到了 DMatrix,因为 DMatrix 是结构体,运行在栈上,执行效率高。
Bentley 中使用 DTransform3d 来实现三维变换,它使用三维矩阵加上一个平移矩阵的方式来表达齐次矩阵。
Bentley 在进行三维仿射时,其原理是先将 DTransform3d 中的数据转成一个三维齐次矩阵,然后再对图形左乘变换矩阵进行变换。
左乘
要对图形进行仿射变换,需要左乘矩阵,同时,变换的顺序是从右向左的。
Bentley
中很多对象重载了运算符,可以方便进行仿射变换,在使用的过程中,直接使用
*
号即可。
例如: 对 DVector3d 进行变换,可以使用:
1 | DVector3d vector = DVector3d.UnitZ; |
关于矩阵的理解
矩阵的通用表达式为: \[ M_{local} \cdot P_{local} = M_{world} \cdot P_{world} = I \cdot P \] 从上面的表达式中,我们可以理解为:
- 对象的真实坐标为 \(P\)
- P 在世界坐标系中是 \(P_{world}\)
- P 在局部坐标系中是 \(P_{local}\)
所以,如果要将一个坐标系转换到另一个坐标系,可以先将该坐标系中的点转换到真实坐标,然后再通过真实坐标转换到另一个坐标系中。
假设有坐标系: \[ \begin{align} M_1 \cdot P_1 = M \cdot P \\ M_2 \cdot P_2 = M \cdot P \end{align} \] 如果要将 \(P_1\) 变成 \(P_2\),则可以: \[ M_1 \cdot P_1 = M_2 \cdot P_2 => P_2 = M_2^{-1} \cdot M_1 \cdot P_1 \] 要转换到某个坐标系,就要左乘该坐标系的逆矩阵。
混淆概念解析
在使用 DTranform3 时,经常会有 worldToLocal
和
localToWorld
,它们的关系如下: \[
\begin{align}
P_{world} = M_{localToWorld} \cdot P_{local} \\
M_{worldToLocal} = M_{localToWorld}^{-1}
\end{align}
\]
worldToLocal
将世界坐标系转换到局部坐标系,从而获取局部坐标,即是局部坐标系矩阵的逆矩阵。
对于元素来说,就是将世界坐标系中的元素旋转到自己定义的坐标系下
localToWorld
worldToLocal的逆矩阵
求逆变换
逆矩阵
在 DTransform3d
的实例上,有一个
TryInvert
,调用该方法可以获取一个变换的逆变换。因为一个矩阵,不一定是可逆的,所以
TryInvert
不一定会获取到逆变换,需要根据返回值来确定。
1 | // 使用代码片段 |
伪逆
一个矩阵不一定有逆矩阵,但是一定有伪逆。所以可以通过下列方法求得:
1 | // DTransform 中包含静态 FromPseudoInverse,直接调用即可 |