使用特征值有效地将球坐标转换为笛卡尔坐标



我需要使用特征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对几何变换有支持函数。但我还没有看到一个明确的例子来实现同样的目标。是否也可以将代码向量化以提高性能?

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

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目前无法自动重用公共子表达式(。

此外,如果您将输入和输出存储为行主格式,那么末尾的乘法可以更好地向量化(尽管Eigen逗号初始化器目前似乎不适合向量化(。

最新更新