How to distribute points evenly within a polygon?

Asked

Viewed 133 times

3

Using the Google Maps API, I’m creating some random dots (custom markers) inside a polygon. I created, at first, a function in which I traverse a loop of 100 positions and randomly distribute the points inside the polygon. If the generated coordinate falls outside the polygon, the same is not drawn on the map, causing it does not always generate 100 points within it. See the magic happening:

function initialize() {
  var bounds = new google.maps.LatLngBounds();
  var i;

  var polygonCoords = [
    new google.maps.LatLng(-23.554548, -46.607911),
    new google.maps.LatLng(-23.556043, -46.595058),
    new google.maps.LatLng(-23.564403, -46.593942),
    new google.maps.LatLng(-23.567884, -46.604757)
  ];


  for (i = 0; i < polygonCoords.length; i++) {
    bounds.extend(polygonCoords[i]);
  }

  var map = new google.maps.Map(document.getElementById("map_canvas2"), {
    zoom: 14,
    center: bounds.getCenter(),
    mapTypeId: "roadmap"
  });

  var sp_mooca = new google.maps.Polygon({
    paths: polygonCoords,
    strokeColor: '#000000',
    strokeOpacity: 0.5,
    strokeWeight: 2,
    fillColor: '#000000',
    fillOpacity: 0.2
  });
  sp_mooca.setMap(map);

  gerarPontosAleatoriosNoPoligono(sp_mooca, map)
}

function gerarPontosAleatoriosNoPoligono(poli, map) {

  var bounds = new google.maps.LatLngBounds();

  for (var i = 0; i < poli.getPath().getLength(); i++) {
    bounds.extend(poli.getPath().getAt(i));
  }
  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.poly.containsLocation(point, poli)) {

      var marker = new google.maps.Marker({
        position: point,
        map: map,
        icon: {
          path: google.maps.SymbolPath.CIRCLE,
          fillColor: "#0000ff",
          fillOpacity: 0.8,
          strokeColor: 'white',
          strokeWeight: .5,
          scale: 4
        }
      });
    }
  }
}
#map {
  height: 100%;
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>

<body onload="initialize()">
  <div id="map_canvas2" style="height: 100vh; width:100vw"></div>
</body>

However, in reality I would like these points to be distributed evenly, with equal spacings, within this polygon, and not randomly, as for example 50 meters apart. How could I do that? How can I distribute dots(markers) evenly within a polygon?

  • Ever tried the good old Cartesian grid? There you identify of is inside the polygon and, if it is, does not draw.

  • 1

    @Jeffersonquesado The logic of the drawing is right, this top code already does. What would really be missing is to actually create a grid, or something similar. xD

  • Very Javascript for me to try from the mobile phone... but it can help: take the coordinates more to the left and the most to the right, take ten slices of the difference; I do the same for the coordinates more to the south is more to the north; use the smallest of these found factors. For NS going from the southernmost to the northernmost in this step, for LO going from the westernmost to the easternmost in this step, check if NS,LO is inside the polygon and if yes draw this point

  • 1

    It is not such a simple thing, and it depends on the desired "precision". You can start from a predefined grid and change the scale until you fit the desired number of points (for example a "triangle grid", if you can call it a grid), or something more complex (who knows how to adapt something "crazy" as Floyd-Steinberg that wasn’t made for this...). Maybe here you will find something https://duckduckgo.com/? q=Evenly+points+Polygon

1 answer

0

You can use the function while, instead of using the for, thus remaining:

var contador = 0;

while(contador <= 100){

    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.poly.containsLocation(point, poli)) {

      contador++;

      var marker = new google.maps.Marker({
        position: point,
        map: map,
        icon: {
          path: google.maps.SymbolPath.CIRCLE,
          fillColor: "#0000ff",
          fillOpacity: 0.8,
          strokeColor: 'white',
          strokeWeight: .5,
          scale: 4
        }
      });
    }
  }

This way he will repeat the while until it reaches 100 and will only be added one more to variable counter if it enters the if and create a bookmark.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.