Published
Edited
May 17, 2018
4 forks
Importers
17 stars
Also listed in…
Cartographic Experiments
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
/*
Generate points at random locations inside polygon.
polygon: polygon (Array of points [x,y])
numPoints: number of points to generate

Returns an Array of points [x,y].

The returned Array will have a property complete, which is set to false if the
desired number of points could not be generated within `options.numIterations` attempts
*/
function makeDots(polygon, numPoints, options) {

options = Object.assign({
// DEFAULT OPTIONS:
maxIterations: numPoints * 50,
distance: null, // by default: MIN(width, height) / numPoints / 4,
edgeDistance: options.distance
},options);

numPoints = Math.floor(numPoints)

// calculate bounding box
let xMin = Infinity,
yMin = Infinity,
xMax = -Infinity,
yMax = -Infinity
polygon.forEach(p => {
if (p[0]<xMin) xMin = p[0]
if (p[0]>xMax) xMax = p[0]
if (p[1]<yMin) yMin = p[1]
if (p[1]>yMax) yMax = p[1]
});

let width = xMax - xMin
let height = yMax - yMin
// default options depending on bounds
options.distance = options.distance || Math.min(width, height) / numPoints / 4
options.edgeDistance = options.edgeDistance || options.distance
// generate points
let points = [];
outer:
for (let i=0; i<options.maxIterations; i++) {
let p = [xMin + Math.random() * width, yMin + Math.random() * height]
if (d3.polygonContains(polygon, p)) {
// check distance to other points
for (let j=0; j<points.length; j++) {
let dx = p[0]-points[j][0],
dy = p[1]-points[j][1]
if (Math.sqrt(dx*dx+dy*dy) < options.distance) continue outer;
}
// check distance to polygon edge
for (let j=0; j<polygon.length-1; j++) {
if (distPointEdge(p, polygon[j], polygon[j+1]) < options.edgeDistance) continue outer;
}
points.push(p);
if (points.length == numPoints) break;
}
}
points.complete = (points.length >= numPoints)
return points
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more