block by Fil 1b7ddbcd71454d685d1259781968aefc

Voronoi.find(x,y)

Full Screen

voronoi.find(x,y) finds the nearest cell to the point (x,y).

Usage:

Original work by Philippe Rivière for d3-voronoi (available since v4.3.0).

See also the Spherical geoVoronoi.find().

Voronoi tesselation forked from mbostock’s block.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.links {
  stroke: #000;
  stroke-opacity: 0.2;
}

.polygons {
  fill: none;
  stroke: #000;
}

.polygons.found {
  fill: #f00;
}

.sites {
  fill: #000;
  stroke: #fff;
}


  
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

var svg = d3.select("svg").on("touchmove mousemove", moved),
    width = +svg.attr("width"),
    height = +svg.attr("height");

var sites = d3.range(1000)
    .map(function(d) { return [Math.random() * (width - 80) + 40, Math.random() * (height-80) + 40]; });

var voronoi = d3.voronoi() 
    .extent([[30, 30], [width - 30, height - 30]]);

var polygon = svg.append("g")
    .attr("class", "polygons")
  .selectAll("path")
  .data(voronoi.polygons(sites))
  .enter().append("path")
    .call(redrawPolygon);

var diagram = voronoi(sites);

// voronoi.find is included in [d3 v4.3.0](https://github.com/d3/d3/releases/v4.3.0)
// the following lines just add coloring
diagram.find = function(x, y, radius) {
  var i, next = diagram.find.found || Math.floor(Math.random() * diagram.cells.length);
  var cell = diagram.cells[next] || diagram.cells[next=0];
  var dx = x - cell.site[0], 
      dy = y - cell.site[1],
      dist = dx*dx + dy*dy;
  

  do {
    cell = diagram.cells[i=next];
    next = null;
    polygon._groups[0][i].setAttribute('fill', '#f5a61d');
    cell.halfedges.forEach(function(e) {
      var edge = diagram.edges[e];
      var ea = edge.left;
      if (ea === cell.site || !ea) {
        ea = edge.right;
      }
      if (ea){
        if (polygon._groups[0][ea.index].getAttribute('fill') != '#f5a61d')
        polygon._groups[0][ea.index].setAttribute('fill', '#fbe8ab');
				var dx = x - ea[0],
            dy = y - ea[1],
            ndist = dx*dx + dy*dy;
        if (ndist < dist){
          dist = ndist;
          next = ea.index;
          return;
        }
      }
    });

  } while (next !== null);

  diagram.find.found = i;
  if (!radius || dist < radius * radius) return cell.site;
} 


findcell([width/2, height/2]);

function moved() {
  findcell(d3.mouse(this));
}

function findcell(m) {
  polygon.attr('fill', '');
	var found = diagram.find(m[0],m[1], 50);
  if (found)
    polygon._groups[0][found.index].setAttribute('fill', 'red');
}

function redraw() {
  polygon = polygon.data(diagram.polygons()).call(redrawPolygon);
}

function redrawPolygon(polygon) {
  polygon
      .attr("d", function(d) { return d ? "M" + d.join("L") + "Z" : null; });
}


</script>