| 1 | "use strict";
|
|---|
| 2 |
|
|---|
| 3 | Object.defineProperty(exports, "__esModule", {
|
|---|
| 4 | value: true
|
|---|
| 5 | });
|
|---|
| 6 | exports.circles = exports.cells = exports.beaches = void 0;
|
|---|
| 7 | exports.default = Diagram;
|
|---|
| 8 | exports.epsilon2 = exports.epsilon = exports.edges = void 0;
|
|---|
| 9 | var _Beach = require("./Beach");
|
|---|
| 10 | var _Cell = require("./Cell");
|
|---|
| 11 | var _Circle = require("./Circle");
|
|---|
| 12 | var _Edge = require("./Edge");
|
|---|
| 13 | var _RedBlackTree = _interopRequireDefault(require("./RedBlackTree"));
|
|---|
| 14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|---|
| 15 | var epsilon = exports.epsilon = 1e-6;
|
|---|
| 16 | var epsilon2 = exports.epsilon2 = 1e-12;
|
|---|
| 17 | var beaches;
|
|---|
| 18 | var cells;
|
|---|
| 19 | var circles;
|
|---|
| 20 | var edges;
|
|---|
| 21 | function triangleArea(a, b, c) {
|
|---|
| 22 | return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
|
|---|
| 23 | }
|
|---|
| 24 | function lexicographic(a, b) {
|
|---|
| 25 | return b[1] - a[1] || b[0] - a[0];
|
|---|
| 26 | }
|
|---|
| 27 | function Diagram(sites, extent) {
|
|---|
| 28 | var site = sites.sort(lexicographic).pop(),
|
|---|
| 29 | x,
|
|---|
| 30 | y,
|
|---|
| 31 | circle;
|
|---|
| 32 | exports.edges = edges = [];
|
|---|
| 33 | exports.cells = cells = new Array(sites.length);
|
|---|
| 34 | exports.beaches = beaches = new _RedBlackTree.default();
|
|---|
| 35 | exports.circles = circles = new _RedBlackTree.default();
|
|---|
| 36 | while (true) {
|
|---|
| 37 | circle = _Circle.firstCircle;
|
|---|
| 38 | if (site && (!circle || site[1] < circle.y || site[1] === circle.y && site[0] < circle.x)) {
|
|---|
| 39 | if (site[0] !== x || site[1] !== y) {
|
|---|
| 40 | (0, _Beach.addBeach)(site);
|
|---|
| 41 | x = site[0], y = site[1];
|
|---|
| 42 | }
|
|---|
| 43 | site = sites.pop();
|
|---|
| 44 | } else if (circle) {
|
|---|
| 45 | (0, _Beach.removeBeach)(circle.arc);
|
|---|
| 46 | } else {
|
|---|
| 47 | break;
|
|---|
| 48 | }
|
|---|
| 49 | }
|
|---|
| 50 | (0, _Cell.sortCellHalfedges)();
|
|---|
| 51 | if (extent) {
|
|---|
| 52 | var x0 = +extent[0][0],
|
|---|
| 53 | y0 = +extent[0][1],
|
|---|
| 54 | x1 = +extent[1][0],
|
|---|
| 55 | y1 = +extent[1][1];
|
|---|
| 56 | (0, _Edge.clipEdges)(x0, y0, x1, y1);
|
|---|
| 57 | (0, _Cell.clipCells)(x0, y0, x1, y1);
|
|---|
| 58 | }
|
|---|
| 59 | this.edges = edges;
|
|---|
| 60 | this.cells = cells;
|
|---|
| 61 | exports.beaches = beaches = exports.circles = circles = exports.edges = edges = exports.cells = cells = null;
|
|---|
| 62 | }
|
|---|
| 63 | Diagram.prototype = {
|
|---|
| 64 | constructor: Diagram,
|
|---|
| 65 | polygons: function () {
|
|---|
| 66 | var edges = this.edges;
|
|---|
| 67 | return this.cells.map(function (cell) {
|
|---|
| 68 | var polygon = cell.halfedges.map(function (i) {
|
|---|
| 69 | return (0, _Cell.cellHalfedgeStart)(cell, edges[i]);
|
|---|
| 70 | });
|
|---|
| 71 | polygon.data = cell.site.data;
|
|---|
| 72 | return polygon;
|
|---|
| 73 | });
|
|---|
| 74 | },
|
|---|
| 75 | triangles: function () {
|
|---|
| 76 | var triangles = [],
|
|---|
| 77 | edges = this.edges;
|
|---|
| 78 | this.cells.forEach(function (cell, i) {
|
|---|
| 79 | if (!(m = (halfedges = cell.halfedges).length)) return;
|
|---|
| 80 | var site = cell.site,
|
|---|
| 81 | halfedges,
|
|---|
| 82 | j = -1,
|
|---|
| 83 | m,
|
|---|
| 84 | s0,
|
|---|
| 85 | e1 = edges[halfedges[m - 1]],
|
|---|
| 86 | s1 = e1.left === site ? e1.right : e1.left;
|
|---|
| 87 | while (++j < m) {
|
|---|
| 88 | s0 = s1;
|
|---|
| 89 | e1 = edges[halfedges[j]];
|
|---|
| 90 | s1 = e1.left === site ? e1.right : e1.left;
|
|---|
| 91 | if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
|
|---|
| 92 | triangles.push([site.data, s0.data, s1.data]);
|
|---|
| 93 | }
|
|---|
| 94 | }
|
|---|
| 95 | });
|
|---|
| 96 | return triangles;
|
|---|
| 97 | },
|
|---|
| 98 | links: function () {
|
|---|
| 99 | return this.edges.filter(function (edge) {
|
|---|
| 100 | return edge.right;
|
|---|
| 101 | }).map(function (edge) {
|
|---|
| 102 | return {
|
|---|
| 103 | source: edge.left.data,
|
|---|
| 104 | target: edge.right.data
|
|---|
| 105 | };
|
|---|
| 106 | });
|
|---|
| 107 | },
|
|---|
| 108 | find: function (x, y, radius) {
|
|---|
| 109 | var that = this,
|
|---|
| 110 | i0,
|
|---|
| 111 | i1 = that._found || 0,
|
|---|
| 112 | n = that.cells.length,
|
|---|
| 113 | cell;
|
|---|
| 114 |
|
|---|
| 115 | // Use the previously-found cell, or start with an arbitrary one.
|
|---|
| 116 | while (!(cell = that.cells[i1])) if (++i1 >= n) return null;
|
|---|
| 117 | var dx = x - cell.site[0],
|
|---|
| 118 | dy = y - cell.site[1],
|
|---|
| 119 | d2 = dx * dx + dy * dy;
|
|---|
| 120 |
|
|---|
| 121 | // Traverse the half-edges to find a closer cell, if any.
|
|---|
| 122 | do {
|
|---|
| 123 | cell = that.cells[i0 = i1], i1 = null;
|
|---|
| 124 | cell.halfedges.forEach(function (e) {
|
|---|
| 125 | var edge = that.edges[e],
|
|---|
| 126 | v = edge.left;
|
|---|
| 127 | if ((v === cell.site || !v) && !(v = edge.right)) return;
|
|---|
| 128 | var vx = x - v[0],
|
|---|
| 129 | vy = y - v[1],
|
|---|
| 130 | v2 = vx * vx + vy * vy;
|
|---|
| 131 | if (v2 < d2) d2 = v2, i1 = v.index;
|
|---|
| 132 | });
|
|---|
| 133 | } while (i1 !== null);
|
|---|
| 134 | that._found = i0;
|
|---|
| 135 | return radius == null || d2 <= radius * radius ? cell.site : null;
|
|---|
| 136 | }
|
|---|
| 137 | }; |
|---|