使用矩阵的3D零件绝对运动

时间:2018-07-09 14:43:11

标签: javascript matrix 3d coordinate-transformation

我正在尝试在相对坐标系和绝对坐标系中实现3D零件的转换。对于相对运动,我能够做到这一点-也就是在局部坐标系中移动零件,但是无法在绝对(全局/模型坐标系)中正确实现。

使用的术语- 1. 3D零件-以3维绘制的任何几何图形(几何图形的组合)。我正在使用在CATIA中创建的零件。 2.局部(相对)坐标系-零件的轴系 3.全局(绝对)坐标系-零件父级的轴系。 4.组装-零件相互连接成仿制。典型的树状结构。 这些定义符合我的用法和理解。 https://www.opengl.org/discussion_boards/showthread.php/127422-Local-and-global-coordinate-system

我的输入-

  1. 矩阵-我为装配体中的每个零件定义了4X4矩阵。这定义了应用了“旋转”,“平移”和“比例”分量的变形矩阵。 Transformation matrix 它的列矩阵在1-10位置的旋转变量,12、13、14(右下方)用于平移。

  2. 运动- 我以绝对或相对单位的x,y,z值向量接收零件运动。 或围绕X,Y或Z轴以度为单位更改旋转。

我尝试了什么-

我按照下面的步骤来转换输入以应用于矩阵。我必须始终将绝对更改转换为相对更改,因为我只能修改叶节点的矩阵(该矩阵始终位于局部坐标系中)。 这是我正在使用的分步操作- Steps for new matrix

第1步-加入LCS。 WCS-世界坐标系; LCS-本地坐标系 第2步-否定LCS中的旋转。备份旋转。 步骤3-将零件移至WCS。 步骤4-在WCS中移动具有所需增量的零件。 步骤5-将零件移回LCS 第6步-再次旋转第1步中保存的后背。

如下所示的伪代码-使用Typescript,但是其他任何语言对我来说也很好。我对矩阵计算更感兴趣。

//// STEP 1//////

    let absVals = Matrix 4;

    /*This is accumulation of all matrices from child to parent. I take all the matrices starting from Child to the root parent and append with matrix multiplication.*/
    let localVals = Matrix4 on the child node. In our case the the box shown in image;
    let localRotation: .Matrix4 = new Matrix4(localVals);
    localRotation.setTranslation(0, 0, 0); // only local rotation matrix

    //// STEP 2//////

    let localTranslation = localVals.multiplyMatrix(localRotation.inverse()); // only local translation. Step 2 achived.

    //// STEP 3//////

    let localInGlobalSpace = localTranslation.multiplyMatrix(res); // move the part in WCS. Step 3 achieved.

    let xDelta = this.xMovement;
    let yDelta = this.yMovement;
    let zDelta = this.zMovement;
    let newPos = new Matrix4();
    newPos.setTranslation(new .Vector3(xDelta, yDelta, zDelta));
    // Similarly rotations should be handled but can skipped for first step

    //// STEP 4//////

    let movedLocalInGlobalSpace = localInGlobalSpace.multiplyMatrix(newPos); // Step 4 achived.

    //// STEP 5//////

    let localBackInLocalSpace = movedLocalInGlobalSpace.multiplyMatrix(absVals.inverse()); // Step 5 achived.

    //// STEP 6//////

    let localBackInLocalSpaceWithRotation = localBackInLocalSpace.multiplyMatrix(localRotation); // Step 6 achived.

我需要帮助来了解我是否在算法中正确执行了这些步骤。 我试图提供尽可能多的信息。让我知道帖子是否变得难以理解。让我知道你的看法。

1 个答案:

答案 0 :(得分:0)

我认为您的问题更多是关于数学变换,而不是代码:

每个变换都可以细分为一个简单的平移和三个旋转(沿每个轴)。现在,我们将只考虑1个平移和1个旋转。

应用旋转时,必须确保旋转中心为原点,即0,0,0。

示例: 如果我们有一个由四个点P1,P2,P3,P4定义的形状,并且我们想要围绕P1施加旋转(矩阵M)并平移(向量V)。

  1. 您必须翻译所有点,才能使P1成为原点。
  2. 将矩阵M应用于“左侧”
  3. 重新转换点,使P1移至先前位置
  4. 应用翻译载体

Formula1

当然,如果旋转中心是其他东西,例如Pc,它将是:

Formula1

如果要否定先前的旋转(矩阵M1),并应用新的旋转(矩阵M2),则请考虑以下事项:

Formula2

关于您的代码:

要小心。在大多数语言/图书馆中:

C = A.mulityplymatrix(B)

手段

Formula2

可以不同于:

Formula3

先应用翻译,然后再应用旋转,会为您提供与先旋转后翻译完全不同的东西。