单位球体表面区域上点的随机样本

Random sample of points on a region of the surface of a unit sphere

我需要生成分布在球体表面 区域 上的点的随机样本。 This answer 给出了一个优雅的方法来对球体的整个表面进行采样:

def sample_spherical(npoints, ndim=3):
    vec = np.random.randn(ndim, npoints)
    vec /= np.linalg.norm(vec, axis=0)
    return vec

(vec returns (x, y, z) 坐标) 结果:

我需要将采样限制在一个矩形区域。该区域由中心值和长度定义,例如:

其中 (ra_0, dec_0)equatorial system 中的坐标,长度以度为单位。

我可以按以下方式使用上述函数:使用大 npoints 调用它,将返回的 (x, y, z) 值转换为赤道系统,拒绝定义区域之外的值,然后重复直到达到所需的样本数。不过,我觉得必须有一种更优雅的方法来实现这一点。

假设您想从 'rectangle' 中随机均匀地采样点 :

  • 随机均匀采样z坐标
  • 随机均匀采样经度
import numpy as np

rad = np.pi / 180

def sample_spherical_rect(npoints, ra_0, dec_0, ra_l, dec_l):
    lon_min = (dec_0 - .5 * dec_l) * rad
    lon_delta = dec_l * rad
    z_min = np.sin((ra_0 - .5 * ra_l) * rad)
    z_max = np.sin((ra_0 + .5 * ra_l) * rad)
    z_delta = z_max - z_min
    z = z_min + np.random.rand(npoints) * z_delta
    lat = np.arcsin(z)
    cos_lat = np.cos(lat)
    lon = lon_min + np.random.rand(npoints) * lon_delta
    x = np.cos(lon) * cos_lat
    y = np.sin(lon) * cos_lat
    return np.array([x,y,z])

说明:单位球面的点具有以下性质:

  • 每个笛卡尔坐标轴 x,y,z 本身在 [-1, 1]

    中是一致的
  • 鉴于

    • x = cos(lon) cos(lat)
    • y = sin(lon) cos(lat)
    • z = 余弦(纬度)

    lon 在 [0, 2pi] 内是均匀的。

  • lon 和 z 在统计上是独立的。

由于球坐标(lat/lon)中的一个矩形等价于mixed坐标(z/lon)中的一个矩形,所以只需要均匀采样在您想要的范围内随机在 (z / lon) 中,然后将 z 和 lon 转换为 x 和 y。

进一步说明

由于从单位球体中采样的点 (x,y,z) 在每个笛卡尔坐标中具有均匀分布似乎并不明显:

a <= z <= b-1 <= a < b <= 1)界定的单位球体的切片的表面由(我可以输入乳胶数学东西吗?所以?):

A = int_{arcsin(a)}^{arcsin(b)} d[theta] int_0^{2 pi} d[phi] cos(theta) # cos(theta) is the Jacobian
  = 2 pi [sin(theta)]_{theta=arcsin(a)}^{theta=arcsin(b)}
  = 2 pi * (b - a)