/* -------------------------- */ /* quadPlugin */ /* -------------------------- */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.quadPlugin = global.quadPlugin || {}))); }(this, function (exports) { 'use strict'; function quadPlugin ( x0= 0, y0= 0, x1= 100, y1= 100) { let extent = [ [x1 - 1 , y0 - 1], [x1 + 1 , y1 + 1] ] let bestcandie = function () {} let candidates = 10 var quad = d3.quadtree() // quad .extent(extent) .x(function(d) {return d[0]}) .y(function(d) {return d[1]}) quad.diagonal = function(d, p) { // error: d is undefined var v = p || 1 var s = d.source var t = d.target var rd = 1 + d3.randomNormal(0, v)() // v var r = "M" + s.x + "," + s.y + "C" + (s.x + rd * ((t.x - s.x))) + "," + s.y + " " + (s.x + rd * ((t.x - s.x))) + "," + t.y + " " + t.x + "," + t.y; return r } quad.findmanyothers = function(x, y, r=Infinity, thesemany = 1) { var ret = [] let quadCopy = quad.copy() let limit = Math.min(thesemany, quadCopy.data().length) let found = 0 while (found < limit) { let p = quadCopy.find(x, y, r) if (p == null) { break } else { let px = p.x let py = p.y let dist = (px - x) * (px - x) + (py - y) * (py- y) if (dist > 1.e-6) { ret.push(p) ++found } quadCopy.remove(p) } } return ret } quad.findmany = function(x, y, r=Infinity, thesemany = 1) { var ret = [] let quadCopy = quad.copy() let limit = Math.min(thesemany, quadCopy.data().length) for (let i = 0; i < limit; i++) { let p = quadCopy.find(x, y, r) quadCopy.remove(p) ret.push(p) } return ret } quad.candysearch = function(r=Infinity, polygon = null) { // seach best free spot in polygon with population let fp = [x0 + Math.random() * (x1 - x0), Math.random() * (y1 - y0), 0] // first point quad.add(fp) // let bestcandy = candysearch({ ctr: [0, 0], rds: [width, height - 110], }) let x, y = 0; // x,y is bestCandidate let z2 = 0; // z2 is bestDistance let p // p is point closest to candidate for (let i = 0; i < candidates; ++i) { let c = [x0 + Math.random() * (x1 - x0), y0 + Math.random() * (y1 - y0)] // c random candidate i let isin = true if (polygon) isin = d3.polygonContains(polygon, c) // check relation with polyong let d2 = Infinity if (isin) { p = quad.find(c[0], c[1], 1000) // check relation with population let dx = p ? c[0] - p[0] : r // x delta if p let dy = p ? c[1] - p[1] : r // y delta if p let d2 = dx * dx + dy * dy // distance from candidate to closest } if (d2 > z2) x = c[0], y = c[1], z2 = d2 // further is better } quad.add(p = [x, y]) // add selected point return p // return selected point } quad.bestcandie = function(_) { return arguments.length ? (bestcandie = typeof _ === "function" ? _ : constant(!!_), quad) : bestcandie; } quad.candidates = function (_) { // kandidates return (arguments.length) ? (candidates = _ ,quad) : candidates } quad.rds = function (_) { // radius return (arguments.length) ? (rds = _ ,quad) : rds } return quad } exports.quadPlugin = quadPlugin }));