世界坐标系到用户坐标系的变换

在 OpenCASCADE 中,从世界坐标系(WCS)到用户自定义坐标系(UDCS)的变换矩阵,本质上是一个 仿射变换矩阵,包含 旋转和平移 两个部分。这个矩阵描述了如何将一个点从世界坐标系变换到用户坐标系中。


🧮 一、数学基础

1. 三维坐标系变换的本质

三维空间中,坐标系变换由以下两个部分组成:

  • 旋转(Rotation):描述用户坐标系相对于世界坐标系的朝向。
  • 平移(Translation):描述用户坐标系的原点在世界坐标系中的位置。

因此,最终的变换矩阵是一个 4x4 的仿射变换矩阵,形式如下:

[R11R12R13TxR21R22R23TyR31R32R33Tz0001] \begin{bmatrix} R_{11} & R_{12} & R_{13} & T_x \\ R_{21} & R_{22} & R_{23} & T_y \\ R_{31} & R_{32} & R_{33} & T_z \\ 0 & 0 & 0 & 1 \end{bmatrix} R11R21R310R12R22R320R13R23R330TxTyTz1

其中:

  • $ R $ 是一个 3x3 的旋转矩阵,表示坐标系的旋转。
  • $ T $ 是一个 3D 平移向量,表示用户坐标系的原点在 WCS 中的位置。

🧭 二、用户自定义坐标系的定义

在 OpenCASCADE 中,使用 gp_Ax3 类定义一个三维坐标系,它包含以下三个关键元素:

  • 原点(Location)gp_Pnt,表示坐标系的原点位置。
  • Z 轴方向(Direction)gp_Dir,表示坐标系的主方向(通常为 Z 轴)。
  • X 轴方向(XDirection)gp_Dir,表示坐标系的参考方向(通常为 X 轴)。

通过这三个元素,我们可以构造出完整的正交基:

  • Z 轴:用户指定的 ZDirection
  • X 轴:用户指定的 XDirection
  • Y 轴:通过叉积计算:Y = Z × X

🧮 三、变换矩阵的构建步骤

步骤 1:构造正交基向量

设:

  • $ \vec{X} $:X 轴方向(单位向量)
  • $ \vec{Y} $:Y 轴方向(单位向量)= $ \vec{Z} \times \vec{X} $
  • $ \vec{Z} $:Z 轴方向(单位向量)

这些向量构成用户坐标系的三个正交基。

步骤 2:构造旋转矩阵

旋转矩阵 $ R $ 由这三个基向量构成:

R=[XxYxZxXyYyZyXzYzZz] R = \begin{bmatrix} X_x & Y_x & Z_x \\ X_y & Y_y & Z_y \\ X_z & Y_z & Z_z \end{bmatrix} R=XxXyXzYxYyYzZxZyZz

其中 $ X_x, X_y, X_z $ 是 $ \vec{X} $ 的三个分量,依此类推。

步骤 3:构造平移向量

平移向量 $ T $ 是用户坐标系的原点在世界坐标系中的坐标:

T=[x0y0z0] T = \begin{bmatrix} x_0 \\ y_0 \\ z_0 \end{bmatrix} T=x0y0z0

步骤 4:组合成仿射变换矩阵

将旋转和平移组合成 4x4 的仿射变换矩阵:

M=[XxYxZxx0XyYyZyy0XzYzZzz00001] M = \begin{bmatrix} X_x & Y_x & Z_x & x_0 \\ X_y & Y_y & Z_y & y_0 \\ X_z & Y_z & Z_z & z_0 \\ 0 & 0 & 0 & 1 \end{bmatrix} M=XxXyXz0YxYyYz0ZxZyZz0x0y0z01


🧪 四、代码实现(手动构建变换矩阵)

#include <gp_Ax3.hxx>
#include <gp_Mat.hxx>
#include <gp_XYZ.hxx>
#include <iostream>

int main()
{
    // 1. 定义用户坐标系
    gp_Pnt origin(10.0, 20.0, 30.0); // 原点
    gp_Dir zAxis(0.0, 0.0, 1.0);     // Z轴方向
    gp_Dir xAxis(1.0, 0.0, 0.0);     // X轴方向

    gp_Ax3 userCS(origin, zAxis, xAxis); // 构造坐标系

    // 2. 获取基向量
    gp_Dir X = userCS.XDirection(); // X 轴
    gp_Dir Y = userCS.YDirection(); // Y 轴(自动计算)
    gp_Dir Z = userCS.Direction();  // Z 轴

    // 3. 构造旋转矩阵
    gp_Mat R(
        X.X(), Y.X(), Z.X(),
        X.Y(), Y.Y(), Z.Y(),
        X.Z(), Y.Z(), Z.Z()
    );

    // 4. 构造平移向量
    gp_XYZ T(origin.X(), origin.Y(), origin.Z());

    // 5. 构造 4x4 仿射变换矩阵(手动)
    double matrix[16] = {
        X.X(), Y.X(), Z.X(), T.X(),
        X.Y(), Y.Y(), Z.Y(), T.Y(),
        X.Z(), Y.Z(), Z.Z(), T.Z(),
        0.0,   0.0,   0.0,   1.0
    };

    // 6. 打印矩阵
    std::cout << "手动构造的变换矩阵:" << std::endl;
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            std::cout << matrix[i * 4 + j] << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

📌 五、关键点总结

项目说明
变换矩阵构成4x4 仿射矩阵,包含旋转和平移
旋转矩阵构造由用户坐标系的三个正交基向量构成
平移向量用户坐标系的原点在世界坐标系中的坐标
基向量顺序通常为 X、Y、Z,其中 Y 由 Z × X 得到
OpenCASCADE 支持gp_Ax3::Transformation() 可直接获取变换矩阵
手动构建适用场景需要深入理解变换原理、调试、或与第三方库交互

🧠 六、扩展理解:变换矩阵的逆

如果你需要 从用户坐标系变换回世界坐标系,可以使用 逆变换矩阵,即:

M−1=[RT−RT⋅T01] M^{-1} = \begin{bmatrix} R^T & -R^T \cdot T \\ 0 & 1 \end{bmatrix} M1=[RT0RTT1]

在 OpenCASCADE 中,可以通过 gp_Trsf::Inverted() 获取逆变换。


📌 七、总结

问题解答
如何手动构造 WCS 到 UDCS 的变换矩阵?构造旋转矩阵(由用户坐标系的三个正交基向量构成)和平移向量(原点)
变换矩阵的数学形式是什么?4x4 仿射矩阵,包含旋转和平移
如何获取逆变换?使用 gp_Trsf::Inverted() 或手动计算逆矩阵
如何验证变换是否正确?将原点变换到用户坐标系中,应得到 (0, 0, 0)
为什么需要手动构造变换矩阵?理解底层原理、调试、与第三方库交互、自定义变换逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值