簡體   English   中英

如何使用 4x4 矩陣轉換頂點矩陣?

[英]How to transform a matrix of vertices using a 4x4 matrix?

我有一個MatrixXd的輸入,其中每一代表一個vertex 我需要使用Matrix4d轉換的輸入來轉換所有這些頂點。

int main(int argc, char** argv)
{
    double arrVertices[] = {
        -1.0 , -1.0 , -1.0 ,
        1.0 , -1.0 , -1.0 ,
        1.0 , 1.0 , -1.0 ,
        -1.0 , 1.0 , -1.0 ,
        -1.0 , -1.0 , 1.0 ,
        1.0 , -1.0 , 1.0 ,
        1.0 , 1.0 , 1.0 ,
        -1.0 , 1.0 , 1.0
    };

    double arrTransformation[] = {
        0.85656139265934328,
        -0.43936858626129838,
        -0.27066182961813096,
        0.00000000000000000,
        0.51460157667407691,
        0.76645256154673991,
        0.38436400479622890,
        0.00000000000000000,
        0.038571983226693918,
        -0.46851437150336084,
        0.88261344075692039,
        0.00000000000000000,
        3.8451662635348320,
        -11.029392777345908,
        19.898165291232520,
        1.0000000000000000
    };

    Eigen::MatrixXd vertices = Eigen::Map<Eigen::Matrix<double, 8, 3>>(arrVertices);
    Eigen::Matrix4d transformation = Eigen::Map<Eigen::Matrix<double, 4, 4>>(arrTransformation);

    for (int i = 0; i < vertices.rows(); ++i) {
        vertices.row(i) = transformation * vertices.row(i); // This causes "INVALID_MATRIX_PRODUCT"
    }
}

從您對矩陣的描述來看,您似乎正在嘗試將仿射變換(旋轉 + 平移)應用於一組頂點。 我鼓勵您閱讀上面鏈接或這個鏈接中的數學解釋,但這里有一個快速的 TLDR:

您的變換矩陣不僅僅代表線性變換。 線性變換(例如,旋轉R )由 3x3 矩陣表示。 您可以將 3D 頂點v乘以 3x3 矩陣以獲得轉換后的頂點,例如v' = R v

在這里您要應用兩個變換:旋轉R (3x3 矩陣)和平移t ,即您想要v' = R v + t

在許多計算機圖形應用程序中,這種變換以 4x4 矩陣表示,其中

  • 頂部 3x3 元素是旋轉矩陣
  • 最后一列是平移向量
  • 最后一行是 [0,0,0,1]

這正是您的矩陣的結構方式:

 0.856561  0.514602  0.038572   3.84517
-0.439369  0.766453 -0.468514  -11.0294
-0.270662  0.384364  0.882613   19.8982
        0         0         0         1

如果將這個 4x4 變換矩陣與頂點相乘,數學就可以計算出來。 這不適用於 3D 頂點本身(您不能將 4x4 矩陣與 3D 向量相乘)。 為了使技巧起作用,您需要添加 1 作為第 4 個坐標(這稱為齊次坐標;您可以嘗試查看數學以查看它是否進行了旋轉和平移。)

幸運的是,Eigen 中有一個Transform類可以為您做到這一點。 您需要從 4x4 矩陣創建一個 Transform 並直接乘以 3D 向量(它在引擎蓋下進行齊次坐標轉換)。 請注意,您需要將頂點放在列中才能工作,因此我們將轉置您的矩陣。

 Eigen::Matrix<double,8, 3> vertices = Eigen::Map<Eigen::Matrix<double, 8, 3>>(arrVertices);
 Eigen::Matrix4d transformation_matrix = Eigen::Map<Eigen::Matrix<double, 4, 4>>(arrTransformation);

 // Create a 3D affine transform
 Eigen::Transform<double, 3, Eigen::Affine> transform(transformation_matrix);
 // Transpose the vertices to put them in columns and transform them :
 cout << transform * vertices.transpose() << endl;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM