使用本征有效地从球面坐标转换为笛卡尔坐标

时间:2018-07-27 10:13:21

标签: performance c++11 eigen

我需要使用Eigen C ++库将坐标从球面空间转换为笛卡尔空间。以下代码可达到目的。

 const int size = 1000;
    Eigen::Array<std::pair<float, float>, Eigen::Dynamic, 1> direction(size);
    for(int i=0; i<direction.size();i++)
    {
            direction(i).first = (i+10)%360; // some value for this example (denoting the azimuth angle)
            direction(i).second = (i+20)%360; // some value for this example (denoting the elevation angle)

     }

    SSPL::MatrixX<T1> transformedMatrix(3, direction.size());
    for(int i=0; i<transformedMatrix.cols(); i++)
    {
        const T1 azimuthAngle = direction(i).first*M_PI/180;    //converting to radians
        const T1 elevationAngle = direction(i).second*M_PI/180; //converting to radians

        transformedMatrix(0,i) = std::cos(azimuthAngle)*std::cos(elevationAngle);
        transformedMatrix(1,i) = std::sin(azimuthAngle)*std::cos(elevationAngle);
        transformedMatrix(2,i) = std::sin(elevationAngle);
    }

我想知道更好的实现方式可以提高速度。 我知道Eigen具有几何转换的辅助功能。但是我还没有看到实现相同目标的明确示例。 还可以对代码进行矢量化以提高性能吗?

1 个答案:

答案 0 :(得分:0)

您至少可以使用正弦/余弦的矢量化版本:

void dir2vector2(Eigen::Matrix3Xf& out, const Eigen::Array2Xf& in){
    Eigen::Array2Xf sine = sin(in * (M_PI/180));
    Eigen::Array2Xf cosi = cos(in * (M_PI/180));

    out.resize(3, in.cols());

    out << cosi.row(0) * cosi.row(1),
           sine.row(0) * cosi.row(1),
                         sine.row(1);
}

仍然存在很多优化潜力,例如,计算相同角度的正弦和余弦会共享很多计算量。从技术上讲,没有必要将sinecosi显式存储到临时变量中(但是Eigen当前无法自动重用common-sub表达式)。

此外,如果以行主格式存储输入和输出,则可以更好地对最后的乘法进行矢量化处理(尽管Eigen逗号初始化器当前不适用于矢量化处理)。