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

如何使用Eigen::Vector模板?向量基类及泛型兼容问题咨询

Eigen向量模板使用与泛型函数改造

问题解答

1. 如何使用Eigen::Vector的模板?

Eigen的向量模板可通过Eigen::Vector<typename Scalar, int Size>直接声明,比如常用的Vector3d本质是Eigen::Vector<double, 3>的别名,Vector3f对应Eigen::Vector<float, 3>。你也可以定义动态大小向量,比如Eigen::VectorXf是Eigen::Vector<float, Eigen::Dynamic>的别名,适用于长度不确定的场景。

2. Eigen中是否存在类似MatrixBase的向量基类?

存在,**Eigen::VectorBase<Derived>**是所有Eigen向量类的统一基类,和MatrixBase对应。它封装了向量专属操作(如点积dot、叉积cross),同时继承自MatrixBase,因此也支持矩阵的通用方法。

泛型函数改造方案

要让函数同时兼容MatrixXd/MatrixXf和Vector3d/Vector3f,需为向量参数添加模板约束,并保证矩阵与向量的标量类型一致。修改后的代码如下:

#include <Eigen/Core>
#include <cmath>
#include <type_traits>

template <typename MatrixDerived, typename VectorDerived>
void test(Eigen::MatrixBase<MatrixDerived>& R, const double deg, const Eigen::VectorBase<VectorDerived>& u) {
    // 编译期检查:向量必须是3维
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorDerived, 3);
    // 编译期检查:矩阵与向量的标量类型必须一致
    EIGEN_STATIC_ASSERT((std::is_same_v<typename MatrixDerived::Scalar, typename VectorDerived::Scalar>),
                        MATRIX_AND_VECTOR_MUST_SHARE_SAME_SCALAR_TYPE);

    using Scalar = typename MatrixDerived::Scalar;
    const Scalar rad = static_cast<Scalar>(deg * M_PI / 180.0); // 转换为弧度(Eigen三角函数默认用弧度)
    const Scalar cos_val = std::cos(rad);
    const Scalar sin_val = std::sin(rad);
    const Scalar one_minus_cos = Scalar(1) - cos_val;

    R = MatrixDerived::Identity(3, 3);
    const auto u_ = u.normalized(); // 直接调用内置归一化方法

    for (int i = 0; i < 3; ++i) {
        auto v = R.col(i);
        R.col(i) = v * cos_val + u_.cross(v) * sin_val + one_minus_cos * (u_.dot(v)) * u_;
    }
}

关键改动说明

  • 新增VectorDerived模板参数,用Eigen::VectorBase<VectorDerived>作为参数类型,兼容所有Eigen向量类型。
  • 加入编译期断言,提前排除不符合要求的输入(非3维向量、标量类型不匹配),避免运行时错误。
  • 使用typename MatrixDerived::Scalar统一标量类型,适配double/float等不同精度。
  • 修正原代码的角度单位问题:将输入的角度转换为弧度,因为Eigen的三角函数默认接受弧度参数。
  • 替换手动归一化逻辑为Eigen内置的normalized()方法,代码更简洁且避免除以零的潜在问题(normalized()会处理零向量情况)。

使用示例

// 测试double精度
Eigen::MatrixXd R_d(3, 3);
Eigen::Vector3d u_d(1, 0, 0);
test(R_d, 90.0, u_d);

// 测试float精度
Eigen::MatrixXf R_f(3, 3);
Eigen::Vector3f u_f(0, 1, 0);
test(R_f, 45.0, u_f);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:13:26