在某个位置周围生成随机坐标

2022-08-30 17:51:26

我希望有一个函数,它接受地理位置(纬度,经度)并围绕它生成随机的坐标集,但也将这些参数作为计算的一部分:

  • 要创建的随机坐标数
  • 要生成的半径
  • 随机坐标之间的最小距离(以米为单位)
  • 根坐标以生成其周围的位置。

如何生成示例:

Example

实现此目的的好方法是什么?


答案 1

在某个位置周围生成随机坐标

function generateRandomPoint($centre, $radius) {
    $radius_earth = 3959; //miles

    //Pick random distance within $distance;
    $distance = lcg_value()*$radius;

    //Convert degrees to radians.
    $centre_rads = array_map( 'deg2rad', $centre );

    //First suppose our point is the north pole.
    //Find a random point $distance miles away
    $lat_rads = (pi()/2) -  $distance/$radius_earth;
    $lng_rads = lcg_value()*2*pi();


    //($lat_rads,$lng_rads) is a point on the circle which is
    //$distance miles from the north pole. Convert to Cartesian
    $x1 = cos( $lat_rads ) * sin( $lng_rads );
    $y1 = cos( $lat_rads ) * cos( $lng_rads );
    $z1 = sin( $lat_rads );


    //Rotate that sphere so that the north pole is now at $centre.

    //Rotate in x axis by $rot = (pi()/2) - $centre_rads[0];
    $rot = (pi()/2) - $centre_rads[0];
    $x2 = $x1;
    $y2 = $y1 * cos( $rot ) + $z1 * sin( $rot );
    $z2 = -$y1 * sin( $rot ) + $z1 * cos( $rot );

    //Rotate in z axis by $rot = $centre_rads[1]
    $rot = $centre_rads[1];
    $x3 = $x2 * cos( $rot ) + $y2 * sin( $rot );
    $y3 = -$x2 * sin( $rot ) + $y2 * cos( $rot );
    $z3 = $z2;


    //Finally convert this point to polar co-ords
    $lng_rads = atan2( $x3, $y3 );
    $lat_rads = asin( $z3 );

    return array_map( 'rad2deg', array( $lat_rads, $lng_rads ) );
}

用法

generateRandomPoint(array(3.1528, 101.7038), 4);

答案 2

蛮力方法应该足够好。

for each point to generate "n"
  find a random angle
  get the x and y from the angle * a random radius up to max radius
  for each point already generated "p"
     calculate the distance between "n" and "p"
  if "n" satisfies the min distance
     add new point "n"

在 PHP 中,生成新点很容易

$angle = deg2rad(mt_rand(0, 359));
$pointRadius = mt_rand(0, $radius);
$point = array(
   'x' => sin($angle) * $pointRadius,
   'y' => cos($angle) * $pointRadius
);

然后计算两点之间的距离

$distance = sqrt(pow($n['x'] - $p['x'], 2) + pow($n['y'] - $p['y'], 2));

** 编辑 **

为了澄清其他人所说的话,并在做了一些进一步的研究之后(我不是数学家,但这些评论确实让我想知道),这里有一个高斯分布最简单的定义:

如果你在1维中,那么$pointRadius= $x * mt_rand(0,$radius);是可以的,因为当$x具有高斯分布时,$radius和$x之间没有区别。

然而,在2维或更多维中,如果坐标($x,$y,...)具有高斯分布,则半径$radius没有高斯分布。

事实上,$radius^2 在 2 维 [或 k 维数] 中的分布就是所谓的“具有 2 [或 k] 自由度的卡方分布”,前提是 ($x,$y,...) 是独立的,并且具有零均值和相等的方差。

因此,要获得正态分布,必须将生成半径的线更改为

$pointRadius = sqrt(mt_rand(0, $radius*$radius));

正如其他人所建议的那样。


推荐