1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- module.exports = generateBoundsFunction;
- module.exports.generateFunctionBody = generateBoundsFunctionBody;
- const createPatternBuilder = require('./createPatternBuilder');
- function generateBoundsFunction(dimension) {
- let code = generateBoundsFunctionBody(dimension);
- return new Function('bodies', 'settings', 'random', code);
- }
- function generateBoundsFunctionBody(dimension) {
- let pattern = createPatternBuilder(dimension);
- let code = `
- var boundingBox = {
- ${pattern('min_{var}: 0, max_{var}: 0,', {indent: 4})}
- };
- return {
- box: boundingBox,
- update: updateBoundingBox,
- reset: resetBoundingBox,
- getBestNewPosition: function (neighbors) {
- var ${pattern('base_{var} = 0', {join: ', '})};
- if (neighbors.length) {
- for (var i = 0; i < neighbors.length; ++i) {
- let neighborPos = neighbors[i].pos;
- ${pattern('base_{var} += neighborPos.{var};', {indent: 10})}
- }
- ${pattern('base_{var} /= neighbors.length;', {indent: 8})}
- } else {
- ${pattern('base_{var} = (boundingBox.min_{var} + boundingBox.max_{var}) / 2;', {indent: 8})}
- }
- var springLength = settings.springLength;
- return {
- ${pattern('{var}: base_{var} + (random.nextDouble() - 0.5) * springLength,', {indent: 8})}
- };
- }
- };
- function updateBoundingBox() {
- var i = bodies.length;
- if (i === 0) return; // No bodies - no borders.
- ${pattern('var max_{var} = -Infinity;', {indent: 4})}
- ${pattern('var min_{var} = Infinity;', {indent: 4})}
- while(i--) {
- // this is O(n), it could be done faster with quadtree, if we check the root node bounds
- var bodyPos = bodies[i].pos;
- ${pattern('if (bodyPos.{var} < min_{var}) min_{var} = bodyPos.{var};', {indent: 6})}
- ${pattern('if (bodyPos.{var} > max_{var}) max_{var} = bodyPos.{var};', {indent: 6})}
- }
- ${pattern('boundingBox.min_{var} = min_{var};', {indent: 4})}
- ${pattern('boundingBox.max_{var} = max_{var};', {indent: 4})}
- }
- function resetBoundingBox() {
- ${pattern('boundingBox.min_{var} = boundingBox.max_{var} = 0;', {indent: 4})}
- }
- `;
- return code;
- }
|