单位球面赤道坐标指定矩形区域随机采样点生成方法咨询
球面指定赤道坐标矩形区域均匀采样实现方案
你提到的拒绝采样方案在采样区域占比极小时效率会非常低,这里给出直接在目标区域生成均匀采样点的实现,效率比拒绝采样高几个数量级。
实现原理
球面上的均匀采样需要满足两个角度维度的分布特性:
- 赤经(RA)属于方位角,直接在目标区间内均匀采样即可
- 赤纬(Dec)属于极角,采样概率需要和
cos(Dec)成正比,避免高纬度区域过采样,我们可以通过对sin(Dec)做均匀采样实现该分布
代码实现
首先导入依赖,注意所有角度计算默认先转成弧度,最终输出和原sample_spherical接口一致,返回shape为(3, npoints)的笛卡尔坐标数组:
import numpy as np def sample_spherical_rect(ra0, dec0, ra_l, dec_l, npoints): """ 赤道坐标系下球面矩形区域均匀采样 参数: ra0: 中心赤经,单位度 dec0: 中心赤纬,单位度 ra_l: 赤经方向边长,单位度 dec_l: 赤纬方向边长,单位度 npoints: 采样点数量 返回: 采样点(x,y,z)坐标,shape为(3, npoints) """ # 角度转弧度,计算采样边界 ra0_rad = np.deg2rad(ra0) dec0_rad = np.deg2rad(dec0) ra_l_rad = np.deg2rad(ra_l) dec_l_rad = np.deg2rad(dec_l) ra_min = ra0_rad - ra_l_rad / 2 ra_max = ra0_rad + ra_l_rad / 2 dec_min = dec0_rad - dec_l_rad / 2 dec_max = dec0_rad + dec_l_rad / 2 # 边界校验,避免赤纬超出±90度 dec_min = np.clip(dec_min, -np.pi/2, np.pi/2) dec_max = np.clip(dec_max, -np.pi/2, np.pi/2) # 生成均匀采样的赤纬:对sin(dec)均匀采样 u = np.random.rand(npoints) sin_dec = np.sin(dec_min) + u * (np.sin(dec_max) - np.sin(dec_min)) dec = np.arcsin(sin_dec) cos_dec = np.cos(dec) # 生成均匀采样的赤经 v = np.random.rand(npoints) ra = ra_min + v * (ra_max - ra_min) # 转笛卡尔坐标 x = cos_dec * np.cos(ra) y = cos_dec * np.sin(ra) z = np.sin(dec) return np.vstack([x, y, z])
补充说明
- 如果你的采样区域跨了赤经0度/360度的边界,只需要额外加一步对RA值的模360度处理即可
- 本方法生成的点和原有全局采样方法的分布特性完全一致,所有点在目标球面区域内均匀分布,没有采样偏差
- 无论采样区域多小,本方法的时间复杂度都是O(n),不存在拒绝采样的效率浪费问题
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

