vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.8 KiB

  1. /**
  2. * Created by Alex on 2/23/2015.
  3. */
  4. class SpringSolver {
  5. constructor(body, options) {
  6. this.body = body;
  7. this.options = options;
  8. }
  9. solve() {
  10. if (this.options.smoothCurves.enabled == true && this.options.smoothCurves.dynamic == true) {
  11. this._calculateSpringForcesWithSupport();
  12. }
  13. else {
  14. this._calculateSpringForces();
  15. }
  16. }
  17. /**
  18. * this function calculates the effects of the springs in the case of unsmooth curves.
  19. *
  20. * @private
  21. */
  22. _calculateSpringForces() {
  23. var edgeLength, edge, edgeId;
  24. var edges = this.edges;
  25. // forces caused by the edges, modelled as springs
  26. for (edgeId in edges) {
  27. if (edges.hasOwnProperty(edgeId)) {
  28. edge = edges[edgeId];
  29. if (edge.connected === true) {
  30. // only calculate forces if nodes are in the same sector
  31. if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
  32. edgeLength = edge.physics.springLength;
  33. this._calculateSpringForce(edge.from, edge.to, edgeLength);
  34. }
  35. }
  36. }
  37. }
  38. }
  39. /**
  40. * This function calculates the springforces on the nodes, accounting for the support nodes.
  41. *
  42. * @private
  43. */
  44. _calculateSpringForcesWithSupport() {
  45. var edgeLength, edge, edgeId;
  46. var edges = this.edges;
  47. // forces caused by the edges, modelled as springs
  48. for (edgeId in edges) {
  49. if (edges.hasOwnProperty(edgeId)) {
  50. edge = edges[edgeId];
  51. if (edge.connected === true) {
  52. // only calculate forces if nodes are in the same sector
  53. if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
  54. if (edge.via != null) {
  55. var node1 = edge.to;
  56. var node2 = edge.via;
  57. var node3 = edge.from;
  58. edgeLength = edge.physics.springLength;
  59. this._calculateSpringForce(node1, node2, 0.5 * edgeLength);
  60. this._calculateSpringForce(node2, node3, 0.5 * edgeLength);
  61. }
  62. }
  63. }
  64. }
  65. }
  66. }
  67. /**
  68. * This is the code actually performing the calculation for the function above. It is split out to avoid repetition.
  69. *
  70. * @param node1
  71. * @param node2
  72. * @param edgeLength
  73. * @private
  74. */
  75. _calculateSpringForce(node1, node2, edgeLength) {
  76. var dx, dy, fx, fy, springForce, distance;
  77. dx = (node1.x - node2.x);
  78. dy = (node1.y - node2.y);
  79. distance = Math.sqrt(dx * dx + dy * dy);
  80. distance = distance == 0 ? 0.01 : distance;
  81. // the 1/distance is so the fx and fy can be calculated without sine or cosine.
  82. springForce = this.options.springConstant * (edgeLength - distance) / distance;
  83. fx = dx * springForce;
  84. fy = dy * springForce;
  85. node1.fx += fx;
  86. node1.fy += fy;
  87. node2.fx -= fx;
  88. node2.fy -= fy;
  89. }
  90. }
  91. export {SpringSolver};