Произвольная генерация координат внутри круга

сценарий
Я пытаюсь сгенерировать от 500 до 1000 случайных координат (широта, длина), которые лежат в окружности с радиусом 1 километр, где центральная точка расположена в (5.418680, 100.327829). Я пытаюсь закодировать это в php, но мне не удалось это сделать, так как я понятия не имею, какое значение я должен предоставить для $ radius.

$radius = ?;
$origin_x = 5.420525;
$origin_y = 100.319500;

$angle = deg2rad(mt_rand(0, 359));
$pointRadius = mt_rand(0, $radius);

$point[] = array(
'x' => $origin_x + ($pointRadius * cos($angle)),
'y' => $origin_y + ($pointRadius * sin($angle))
);

В моей голове появился другой подход. Вместо генерации точки внутри круга, я хотел бы создать точку внутри границы квадрата, а затем применить формулу расстояния большого круга Хаверсайна, чтобы определить, находится ли случайно созданная точка внутри круга с радиусом 1 км.

Примечание. Сгенерированная точка может перекрывать друг друга.

Пожалуйста, посоветуйте, мне нужно общее представление о том, какой подход я должен использовать. Заранее спасибо.

2

Решение

Создайте случайные точки внутри границ круга:

var bounds = circle.getBounds();
map.fitBounds(bounds);
var sw = bounds.getSouthWest();
var ne = bounds.getNorthEast();
for (var i = 0; i < 100; i++) {
// create a random point inside the bounds
var ptLat = Math.random() * (ne.lat() - sw.lat()) + sw.lat();
var ptLng = Math.random() * (ne.lng() - sw.lng()) + sw.lng();
var point = new google.maps.LatLng(ptLat,ptLng);

Если они находятся внутри самого круга, сохраните их (в этом случае добавьте их на карту), в противном случае откажитесь от них:

   if (google.maps.geometry.spherical.computeDistanceBetween(point,circle.getCenter()) < circle.getRadius()) {
createMarker(map, point,"marker "+i);
// break;  if only need one point
} // else nothing.

Пример использования API JavaScript Карт Google v3:

var circle;
var infowindow = new google.maps.InfoWindow({});

function initialize() {
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 4,
center: new google.maps.LatLng(22.7964, 79.8456),
mapTypeId: google.maps.MapTypeId.HYBRID
});

circle = new google.maps.Circle({
center: map.getCenter(),
radius: 1000, // meters
strokeColor: "#0000FF",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#0000FF",
fillOpacity: 0.26
});

circle.setMap(map);

var bounds = circle.getBounds();
map.fitBounds(bounds);
var sw = bounds.getSouthWest();
var ne = bounds.getNorthEast();
for (var i = 0; i < 100; i++) {
var ptLat = Math.random() * (ne.lat() - sw.lat()) + sw.lat();
var ptLng = Math.random() * (ne.lng() - sw.lng()) + sw.lng();
var point = new google.maps.LatLng(ptLat, ptLng);
if (google.maps.geometry.spherical.computeDistanceBetween(point, circle.getCenter()) < circle.getRadius()) {
createMarker(map, point, "marker " + i);
// break;
}
}

}

function createMarker(map, point, content) {
var marker = new google.maps.Marker({
position: point,
map: map
});
google.maps.event.addListener(marker, "click", function(evt) {
infowindow.setContent(content + "<br>" + marker.getPosition().toUrlValue(6));
infowindow.open(map, marker);
});
return marker;
}
google.maps.event.addDomListener(window, 'load', initialize);
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map" style="width: 530px; height: 500px">
</div>
1

Другие решения

Я бы сделал это так:

  1. Выберите два независимых Икс а также Y координата, равномерно из интервала [0,1].
  2. Если Икс² + Y²> 1 ваша точка находится вне круга. Откажитесь от этого образца и попробуйте снова. Не преобразование квадрата в круг обеспечивает равномерное распределение.
  3. Поверните координаты по кругу в широту / долготу на сфере. Если вы хотите сохранить равнораспределение, вы должны использовать сохраняющая площадь проекция карты Вот. Но так как радиус намного меньше радиуса Земли, это не имеет большого значения, поэтому вы можете вместо этого использовать более простую проекцию, если только вам не нужно предоставлять надежные гарантии для равнораспределения.

Я думаю, что могут быть способы избежать отбрасывания на шаге 2, но это, вероятно, сделает вещи путь более сложным, поэтому для практического применения я бы придерживался этого.

0