You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eigen3:无需存储w分量实现Matrix4d与连续Vector3d相乘

Eigen3中3D向量与4x4矩阵乘法的空间优化方案

问题场景

使用Eigen3处理连续存储的多个Vector3d时,需要与Matrix4d进行乘法运算,但直接操作会遇到矩阵尺寸不匹配的问题。此前的解决方式是在磁盘存储时为每个向量添加w分量转为Vector4d,但希望节省每个向量占用的1个double空间,现有代码如下:

#include <array>
#include <eigen3/Eigen/Geometry>
#include <iostream>

using namespace std;
#define M 4
int main (){
        
#if M == 4
    auto arr = std::to_array( {1., 2., 3., 1., 4., 5., 6., 1.} );
    Eigen::Map<Eigen::MatrixXd> v( arr.data(), 4, 2 );
#elif M == 3
    auto arr = std::to_array( {1., 2., 3., 4., 5., 6.} );
    Eigen::Map<Eigen::MatrixXd> v( arr.data(), 3, 2 );
#endif
    
    // 示例变换矩阵,实际代码中为参数传入的不同矩阵
    Eigen::Matrix4d w;
    w.setIdentity();
    w( 0, 3 ) = 10;
    w( 1, 3 ) = 20;

    cout << v.matrix() << "\n\n";
    cout << w.matrix() << "\n\n";

    auto res = w * v;

    std::cout << res.matrix() << std::endl;
}

解决方案:无需存储w分量,Eigen可自动计算

不需要额外存储w分量,利用Eigen的块操作与广播特性就能完成计算,完全避免空间浪费,分两种场景处理:

1. 针对仿射变换(绝大多数3D变换场景)

如果你的Matrix4d是仿射变换矩阵(最后一行为[0, 0, 0, 1],包含平移、旋转、缩放等常见3D变换),可以直接拆解矩阵运算,跳过w分量的存储:

原理是齐次坐标下的仿射变换展开后,等价于线性变换加平移向量,无需显式构造齐次向量。修改后的代码如下:

#include <array>
#include <eigen3/Eigen/Geometry>
#include <iostream>

using namespace std;
#define M 3
int main (){
        
#if M == 4
    auto arr = std::to_array( {1., 2., 3., 1., 4., 5., 6., 1.} );
    Eigen::Map<Eigen::MatrixXd> v( arr.data(), 4, 2 );
#elif M == 3
    auto arr = std::to_array( {1., 2., 3., 4., 5., 6.} );
    Eigen::Map<Eigen::MatrixXd> v( arr.data(), 3, 2 );
#endif
    
    Eigen::Matrix4d w;
    w.setIdentity();
    w( 0, 3 ) = 10;
    w( 1, 3 ) = 20;

    cout << v.matrix() << "\n\n";
    cout << w.matrix() << "\n\n";

    Eigen::MatrixXd res;
#if M == 4
    res = w * v;
#elif M == 3
    // 直接计算仿射变换结果,无需存储w分量
    res = w.topLeftCorner<3,3>() * v + w.col(3).replicate(1, v.cols());
    // 若需要输出齐次坐标形式(4xN),可按需构造:
    // Eigen::MatrixXd res_homo(4, v.cols());
    // res_homo.topRows<3>() = res;
    // res_homo.row(3).setOnes();
#endif

    std::cout << res.matrix() << std::endl;
}

2. 针对非仿射变换(极少场景)

如果你的Matrix4d不是仿射矩阵(最后一行非[0,0,0,1]),则必须明确每个向量的w分量才能完成正确的齐次坐标运算,这种情况下才需要存储w分量。但这类场景在3D空间变换中非常罕见。

内容的提问来源于stack exchange,提问作者Kroma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:12:18