问题描述
我找到了HEALpix算法this is the dokumentation的实现 输出看起来非常不错。
以下图像显示了将纬度/经度转换为HEALpix区域。 X轴从0变为2 * pi。 y轴从0到pi。灰色代表用灰色编码的HEALpix像素。
不同的灰度值是我必须使用的纹理的ID。这意味着,每个HEALpix像素代表一个纹理。缺少的部分是每个HEALpix像素内的UV映射,如下所示:
现在我正在使用该功能:
void ang2pix_ring( const long nside,double theta,double phi,long *ipix)
哪个可以给我正确的纹理ID。但是我不知道如何为每个HEALpix像素计算UV贴图。 有没有一种方法可以计算HEALpix像素的纬度/经度坐标中的所有四个角?甚至更好地直接计算UV坐标?
顺便说一句:我正在使用RING方案。但是,如果更简单地计算nesTED方案,我也会对此进行更改。
解决方法
经过大量研究,我找到了解决该问题的方法:
首先,我将方案更改为NESTED。使用NESTED方案和很高的nSide值(8192),从
返回的值void ang2pix_ring( const long nside,double theta,double phi,long *ipix)
函数返回一个长值,可以通过以下方式读取UV坐标:
第26位到第30位代表0级(仅12个HEALPix像素)。
通过使用更高的级别,从30到26的位-(级别* 2)表示HEALPix像素。
剩余的26-(级别* 2)-1直到第1位以以下方式编码UV纹理坐标:
每个第二奇数位收缩在一起代表U坐标,偶数代表V坐标。 要标准化这些UV坐标,需要将响应的收缩值除以pow(2,(26-level * 2)/ 2)的值。
代码说了1000多个字:
unsigned long ignoreEverySecondBit(unsigned long value,bool odd,unsigned int countBits)
{
unsigned long result = 0;
unsigned long mask = odd == true ? 0b1 : 0b10;
countBits = countBits / 2;
for (int i = 0; i < countBits; ++i)
{
if ((value & mask) != 0)
{
result += std::pow(2,i);
}
mask = mask << 2;
}
return result;
}
//calculate the HEALPix values:
latLonToHealPixNESTED(nSide,theta,phi,&pix);
result.level = level;
result.texture = pix >> (26 - level * 2);
result.u = static_cast<float>(ignoreEverySecondBit(pix,true,26 - level * 2));
result.v = static_cast<float>(ignoreEverySecondBit(pix,false,26 - level * 2));
result.u = result.u / pow(2,(26 - level * 2) / 2);
result.v = result.v / pow(2,(26 - level * 2) / 2);
当然,有些图像会显示结果。蓝色值代表textureID,红色值代表U坐标,绿色值代表V坐标:
我希望该解决方案也能对其他人有所帮助。