元ネタ
多数の点を球面上に一様分布させる – blog.PanicBlanket.com
static (double colat, double lng, double x, double y, double z)[] GSS(int n)
{
var dst = new (double, double, double, double, double)[n];
dst[0] = (0, 0, 0, 0, 1);
dst[dst.Length - 1] = (Math.PI, 0, 0, 0, -1);
double lng = 0;
for (int i = 1; i < n - 1; i++)
{
var hk = 1 - 2 * i / (double)(n - 1);
lng = (lng + 3.6 / Math.Sqrt(n) / Math.Sqrt(1 - hk * hk)) % (Math.PI * 2);
var colat = Math.Acos(hk);
var x = Math.Sin(colat) * Math.Cos(lng);
var y = Math.Sin(colat) * Math.Sin(lng);
var z = Math.Cos(colat);
dst[i] = (colat, lng, x, y, z);
}
return dst;
}
極座標(colatおよびlng)と直交座標(x,y,z)をタプルで返している。
個人的な好みによって、北天(Z+)から開始するように変更している。他の座標系に変更するときは始点と終点の定数も忘れずに変更すること。
点数nと隣接する2点間の角度(度)は以下のような関係になる。
ただしここではGSS(n)[n/2]とGSS(n)[n/2+1]の2点の座標xyzの内積を2点間の角度としている。
横軸がn、縦軸が度で、例えば約4千点で10度間隔、約4万点で1度間隔になる。
間隔からnを求める場合は大雑把に $n = (deg/211)^{-2}$ または $n = (rad/3.7)^{-2}$ で近似できる。