UNPKG

paths-js

Version:
231 lines (198 loc) 6.37 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); var _ops = require('./ops'); var average = function average(body1, body2) { var mass = body1.mass + body2.mass; var point = (0, _ops.times)(1 / mass, (0, _ops.plus)((0, _ops.times)(body1.mass, body1.point), (0, _ops.times)(body2.mass, body2.point))); return [point, mass]; }; var locate = function locate(_ref, quadrants) { var _ref2 = _slicedToArray(_ref, 2); var x = _ref2[0]; var y = _ref2[1]; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = quadrants[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var q = _step.value; var _q$box = q.box; var _top = _q$box.top; var bottom = _q$box.bottom; var left = _q$box.left; var right = _q$box.right; if (left <= x && x <= right && bottom <= y && y <= _top) { return q; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } }; var makeQuadrant = function makeQuadrant(_ref3, _ref4) { var top = _ref3.top; var bottom = _ref3.bottom; var left = _ref3.left; var right = _ref3.right; var _ref42 = _slicedToArray(_ref4, 2); var a = _ref42[0]; var b = _ref42[1]; var halfwayV = (left + right) / 2; var halfwayH = (top + bottom) / 2; return { box: { top: b ? halfwayH : top, bottom: b ? bottom : halfwayH, left: a ? halfwayV : left, right: a ? right : halfwayV } }; }; var subdivide = function subdivide(_ref5) { var box = _ref5.box; return [makeQuadrant(box, [0, 0]), makeQuadrant(box, [1, 0]), makeQuadrant(box, [0, 1]), makeQuadrant(box, [1, 1])]; }; var addBody = function addBody(root, body) { if (root.body) { var oldBody = root.body; delete root.body; root.children = subdivide(root); addBody(root, oldBody); addBody(root, body); } else { if (root.children) { var child = locate(body.point, root.children); var _ref6 = root.point ? average(root, body) : [body.point, body.mass]; var _ref62 = _slicedToArray(_ref6, 2); var p = _ref62[0]; var m = _ref62[1]; root.point = p; root.mass = m; addBody(child, body); } else { root.body = body; } } }; var makeTree = function makeTree(_x, _x2) { var _again = true; _function: while (_again) { var bodies = _x, root = _x2; _again = false; if (bodies.length === 0) { return root; } else { var body = bodies.shift(); addBody(root, body); _x = bodies; _x2 = root; _again = true; body = undefined; continue _function; } } }; var makeBodies = function makeBodies(positions) { return (0, _ops.mapObject)(positions, function (id, position) { return { id: id, point: position, mass: 1 }; }); }; var makeRoot = function makeRoot(width, height) { return { box: { top: height, bottom: 0, left: 0, right: width } }; }; var walkLeaves = function walkLeaves(tree, f) { if (tree.body) { f(tree); } else { if (tree.children) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = tree.children[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var child = _step2.value; walkLeaves(child, f); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2['return']) { _iterator2['return'](); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } } }; var bodyForceOn = function bodyForceOn(b1, b2, repulsion) { var segment = (0, _ops.minus)(b1.point, b2.point); var d = (0, _ops.length)(segment); return (0, _ops.times)(repulsion * b1.mass * b2.mass / (d * d * d), segment); }; var boxWidth = function boxWidth(_ref7) { var top = _ref7.top; var bottom = _ref7.bottom; var left = _ref7.left; var right = _ref7.right; return (0, _ops.length)([top - bottom, right - left]); }; var forceOn = function forceOn(leaf, tree, repulsion, threshold) { if (tree === leaf) { return [0, 0]; } else if (tree.body) { return bodyForceOn(leaf.body, tree.body, repulsion); } else if (tree.point) { var s = boxWidth(tree.box); var d = (0, _ops.length)((0, _ops.minus)(leaf.body.point, tree.point)); if (s / d < threshold) { return bodyForceOn(leaf.body, tree, repulsion); } else return (0, _ops.sumVectors)(tree.children.map(function (c) { return forceOn(leaf, c, repulsion, threshold); })); } else return [0, 0]; }; var repulsiveForces = function repulsiveForces(tree, repulsion, threshold) { var forces = {}; walkLeaves(tree, function (leaf) { forces[leaf.body.id] = forceOn(leaf, tree, repulsion, threshold); }); return forces; }; exports.tree = makeTree; exports.bodies = makeBodies; exports.root = makeRoot; exports.forces = repulsiveForces; exports['default'] = { tree: makeTree, bodies: makeBodies, root: makeRoot, forces: repulsiveForces };