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.

51 lines
1.7 KiB

  1. import BarnesHutSolver from "./BarnesHutSolver"
  2. /**
  3. * @class ForceAtlas2BasedRepulsionSolver
  4. * @extends BarnesHutSolver
  5. */
  6. class ForceAtlas2BasedRepulsionSolver extends BarnesHutSolver {
  7. /**
  8. * @param {Object} body
  9. * @param {{physicsNodeIndices: Array, physicsEdgeIndices: Array, forces: {}, velocities: {}}} physicsBody
  10. * @param {Object} options
  11. * @constructor ForceAtlas2BasedRepulsionSolver
  12. * @extends BarnesHutSolver
  13. */
  14. constructor(body, physicsBody, options) {
  15. super(body, physicsBody, options);
  16. }
  17. /**
  18. * Calculate the forces based on the distance.
  19. *
  20. * @param {number} distance
  21. * @param {number} dx
  22. * @param {number} dy
  23. * @param {vis.Node} node
  24. * @param {Object} parentBranch
  25. * @private
  26. */
  27. _calculateForces(distance, dx, dy, node, parentBranch) {
  28. if (distance === 0) {
  29. distance = 0.1 * Math.random();
  30. dx = distance;
  31. }
  32. if (this.overlapAvoidanceFactor < 1 && node.shape.radius) {
  33. distance = Math.max(0.1 + (this.overlapAvoidanceFactor * node.shape.radius), distance - node.shape.radius);
  34. }
  35. let degree = (node.edges.length + 1);
  36. // the dividing by the distance cubed instead of squared allows us to get the fx and fy components without sines and cosines
  37. // it is shorthand for gravityforce with distance squared and fx = dx/distance * gravityForce
  38. let gravityForce = this.options.gravitationalConstant * parentBranch.mass * node.options.mass * degree / Math.pow(distance,2);
  39. let fx = dx * gravityForce;
  40. let fy = dy * gravityForce;
  41. this.physicsBody.forces[node.id].x += fx;
  42. this.physicsBody.forces[node.id].y += fy;
  43. }
  44. }
  45. export default ForceAtlas2BasedRepulsionSolver;