在球冠上找到均匀分布的随机点

Find evenly distributed random points on a spherical cap

我有400m-1000m的经纬度和半径组成spherical cap。我需要在那个帽子上找到一个随机点。点必须均匀分布在该区域。

有一个关于查找 random points in a circle 的相关问题。我的第一个想法是将盖子投影到笛卡尔平面上并使用圆算法。半径足够小,应该没有重要的错误级别。

我不确定投影然后将点转换回 lat/lng 是否是最简单的解决方案,或者对于这个问题还有其他可能的解决方案

如维基页面 theta + phi = 90 所述,如果 phi 是纬度。另一方面,由于 r 对于上限上的所有点都是固定的,我们只需要设置 theta 的值。因此,您可以从 0theta 值(与上限相关)中选择一个随机值,并通过解释的约束定义点。

您可以使用 sqrt-distribution 生成 0..360 范围内的随机方位角和随机距离以提供 unifrom 分布

d = maxR * Sqrt(random(0..1))
theta = random(0..1) * 2 * Pi

然后按照所述使用方位角和距离获取地理点坐标 here (Destination point given distance and bearing from start point)

φ2 = asin( sin φ1 ⋅ cos δ + cos φ1 ⋅ sin δ ⋅ cos θ )
λ2 = λ1 + atan2( sin θ ⋅ sin δ ⋅ cos φ1, cos δ − sin φ1 ⋅ sin φ2 )

where   φ is latitude, λ is longitude, θ is the bearing
(clockwise from north), δ is the angular distance d/R; 
d being the distance travelled, R the earth’s radius

对于与球体半径相比非常小的圆盘,经纬度投影将简单地近似为椭圆形,除非您非常靠近两极。

首先计算给定纬度处的拉伸:

double k = cos(latitude * PI / 180);

然后以纬度计算圆盘半径

// A latitude arc-second is 30.87 meters
double R = radius / 30.87 / 3600 * PI / 180;

然后在圆周上计算一个均匀的随机点

double a = random() * 2 * PI;
double r = R * sqrt(random());

你在圆盘中的随机点将是

double random_lat = (latitude*PI/180 + r*cos(a))/PI*180;
double random_longitude = (longitude*PI/180 + (r/k)*sin(a))/PI*180;