Eigen::Map实现4x4矩阵3维旋转缩放无拷贝操作方法
报错核心原因
你的代码报错来自两个低级问题,和Eigen::Map的能力无关:
- 类型不匹配:你映射的是
double精度的Matrix4d,但用的AngleAxisf、Vector3f::UnitZ()都是float精度,且生成的旋转矩阵是3x3维度,和4x4矩阵无法直接相乘。 - 维度不匹配:
Eigen::Scaling(sx,sy,sz)默认生成3x3缩放矩阵,不能直接和4x4齐次变换矩阵做乘法。
另外你对Eigen::Map的认知是错的:它不止支持2/3/4维固定大小矩阵,任意固定/动态维度的矩阵、向量都可以零拷贝映射,完全满足你的无拷贝需求。
修正后无拷贝实现
全程所有操作直接读写原std::array<double,16>的内存,没有任何额外的数据拷贝:
旋转变换代码
#include <array> #include <Eigen/Core> #include <Eigen/Geometry> // 绕Z轴旋转,angle_z为弧度制 void rotate_z(std::array<double, 16>& input_mat, double angle_z) { // 直接映射原数组内存,无拷贝,用data()取指针比强制类型转换更安全 Eigen::Map<Eigen::Matrix4d> mapped_mat(input_mat.data()); // 构造double精度的Z轴旋转,转4x4齐次矩阵,Eigen表达式模板惰性求值无临时拷贝 mapped_mat = Eigen::AngleAxisd(angle_z, Eigen::Vector3d::UnitZ()) .toRotationMatrix() .homogeneous() * mapped_mat; }
缩放变换代码
void scale(std::array<double, 16>& input_mat, double sx, double sy, double sz) { Eigen::Map<Eigen::Matrix4d> mapped_mat(input_mat.data()); // 构造4x4齐次缩放矩阵,直接原地运算 mapped_mat = Eigen::Scaling(sx, sy, sz).toHomogeneousMatrix() * mapped_mat; }
关键说明
- 所有Eigen运算对象统一用
double精度版本(后缀带d,比如AngleAxisd/Vector3d),和映射的Matrix4d类型对齐,避免隐式类型转换的开销和报错。 - 3D空间的旋转、缩放原生是3x3矩阵,必须转成4x4齐次形式(最后一行固定为
[0,0,0,1])才能和4x4变换矩阵相乘。 - 上述代码默认遵循Eigen列优先存储、左乘列向量的变换规则,如果你的原数组是行优先存储、用右乘行向量的逻辑,只需要修改Map的模板参数指定存储顺序,同时调换乘法顺序即可:
// 行优先存储的映射方式 Eigen::Map<Eigen::Matrix<double, 4, 4, Eigen::RowMajor>> mapped_mat(input_mat.data()); // 行向量逻辑下变换右乘 mapped_mat = mapped_mat * Eigen::Scaling(sx,sy,sz).toHomogeneousMatrix(); - 零拷贝验证:
Eigen::Map构造时仅保存原数组的内存指针,不会申请额外内存存储矩阵数据,所有运算直接读写原数组地址,全程无无用数据拷贝。
内容的提问来源于stack exchange,提问作者Kroma
相关产品推荐
相关产品推荐

