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

Eigen::Map实现4x4矩阵3维旋转缩放无拷贝操作方法

报错核心原因

你的代码报错来自两个低级问题,和Eigen::Map的能力无关:

  1. 类型不匹配:你映射的是double精度的Matrix4d,但用的AngleAxisf、Vector3f::UnitZ()都是float精度,且生成的旋转矩阵是3x3维度,和4x4矩阵无法直接相乘。
  2. 维度不匹配: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:36:18