UNPKG

ngraph.forcelayout3d

Version:
59 lines (51 loc) 1.75 kB
/** * Represents 3d spring force, which updates forces acting on two bodies, conntected * by a spring. * * @param {Object} options for the spring force * @param {Number=} options.springCoeff spring force coefficient. * @param {Number=} options.springLength desired length of a spring at rest. */ module.exports = function (options) { var merge = require('ngraph.merge'); var random = require('ngraph.random').random(42); var expose = require('ngraph.expose'); options = merge(options, { springCoeff: 0.8, springLength: 80 }); var api = { /** * Upsates forces acting on a spring */ update : function (spring) { var body1 = spring.from, body2 = spring.to, length = spring.length < 0 ? options.springLength : spring.length, dx = body2.pos.x - body1.pos.x, dy = body2.pos.y - body1.pos.y, dz = body2.pos.z - body1.pos.z, r = Math.sqrt(dx * dx + dy * dy + dz * dz); if (r === 0) { dx = (random.nextDouble() - 0.5) / 50; dy = (random.nextDouble() - 0.5) / 50; dz = (random.nextDouble() - 0.5) / 50; r = Math.sqrt(dx * dx + dy * dy + dz * dz); } var d = r - length; var coeff = ((!spring.coeff || spring.coeff < 0) ? options.springCoeff : spring.coeff) * d / r; body1.force.x += coeff * dx; body1.force.y += coeff * dy; body1.force.z += coeff * dz; body1.springCount += 1; body1.springLength += r; body2.force.x -= coeff * dx; body2.force.y -= coeff * dy; body2.force.z -= coeff * dz; body2.springCount += 1; body2.springLength += r; } }; expose(options, api, ['springCoeff', 'springLength']); return api; }