generateCreateSpringForce.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. const createPatternBuilder = require('./createPatternBuilder');
  2. module.exports = generateCreateSpringForceFunction;
  3. module.exports.generateCreateSpringForceFunctionBody = generateCreateSpringForceFunctionBody;
  4. function generateCreateSpringForceFunction(dimension) {
  5. let code = generateCreateSpringForceFunctionBody(dimension);
  6. return new Function('options', 'random', code);
  7. }
  8. function generateCreateSpringForceFunctionBody(dimension) {
  9. let pattern = createPatternBuilder(dimension);
  10. let code = `
  11. if (!Number.isFinite(options.springCoefficient)) throw new Error('Spring coefficient is not a number');
  12. if (!Number.isFinite(options.springLength)) throw new Error('Spring length is not a number');
  13. return {
  14. /**
  15. * Updates forces acting on a spring
  16. */
  17. update: function (spring) {
  18. var body1 = spring.from;
  19. var body2 = spring.to;
  20. var length = spring.length < 0 ? options.springLength : spring.length;
  21. ${pattern('var d{var} = body2.pos.{var} - body1.pos.{var};', {indent: 6})}
  22. var r = Math.sqrt(${pattern('d{var} * d{var}', {join: ' + '})});
  23. if (r === 0) {
  24. ${pattern('d{var} = (random.nextDouble() - 0.5) / 50;', {indent: 8})}
  25. r = Math.sqrt(${pattern('d{var} * d{var}', {join: ' + '})});
  26. }
  27. var d = r - length;
  28. var coefficient = ((spring.coefficient > 0) ? spring.coefficient : options.springCoefficient) * d / r;
  29. ${pattern('body1.force.{var} += coefficient * d{var}', {indent: 6})};
  30. body1.springCount += 1;
  31. body1.springLength += r;
  32. ${pattern('body2.force.{var} -= coefficient * d{var}', {indent: 6})};
  33. body2.springCount += 1;
  34. body2.springLength += r;
  35. }
  36. };
  37. `;
  38. return code;
  39. }