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.

87 lines
3.1 KiB

  1. /**
  2. * Created by Alex on 2/23/2015.
  3. */
  4. import {BarnesHutSolver} from "./components/physics/BarnesHutSolver";
  5. import {Repulsion} from "./components/physics/RepulsionSolver";
  6. import {HierarchicalRepulsion} from "./components/physics/HierarchicalRepulsionSolver";
  7. import {SpringSolver} from "./components/physics/SpringSolver";
  8. import {HierarchicalSpringSolver} from "./components/physics/HierarchicalSpringSolver";
  9. import {CentralGravitySolver} from "./components/physics/CentralGravitySolver";
  10. class PhysicsEngine {
  11. constructor(body, options) {
  12. this.body = body;
  13. this.physicsBody = {calculationNodes: {}, calculationNodeIndices:[]};
  14. this.setOptions(options);
  15. }
  16. setOptions(options) {
  17. if (options !== undefined) {
  18. this.options = options;
  19. this.init();
  20. }
  21. }
  22. init() {
  23. var options;
  24. if (this.options.model == "repulsion") {
  25. options = this.options.repulsion;
  26. this.nodesSolver = new Repulsion(this.body, this.physicsBody, options);
  27. this.edgesSolver = new SpringSolver(this.body, options);
  28. }
  29. else if (this.options.model == "hierarchicalRepulsion") {
  30. options = this.options.hierarchicalRepulsion;
  31. this.nodesSolver = new HierarchicalRepulsion(this.body, this.physicsBody, options);
  32. this.edgesSolver = new HierarchicalSpringSolver(this.body, this.physicsBody, options);
  33. }
  34. else { // barnesHut
  35. options = this.options.barnesHut;
  36. this.nodesSolver = new BarnesHutSolver(this.body, this.physicsBody, options);
  37. this.edgesSolver = new SpringSolver(this.body, options);
  38. }
  39. this.gravitySolver = new CentralGravitySolver(this.body, this.physicsBody, options);
  40. }
  41. /**
  42. * Smooth curves are created by adding invisible nodes in the center of the edges. These nodes are also
  43. * handled in the calculateForces function. We then use a quadratic curve with the center node as control.
  44. * This function joins the datanodes and invisible (called support) nodes into one object.
  45. * We do this so we do not contaminate this.body.nodes with the support nodes.
  46. *
  47. * @private
  48. */
  49. _updateCalculationNodes() {
  50. this.physicsBody.calculationNodes = {};
  51. this.physicsBody.calculationNodeIndices = [];
  52. for (let i = 0; i < this.body.nodeIndices.length; i++) {
  53. let nodeId = this.body.nodeIndices[i];
  54. this.physicsBody.calculationNodes[nodeId] = this.body.nodes[nodeId];
  55. }
  56. // if support nodes are used, we have them here
  57. var supportNodes = this.body.supportNodes;
  58. for (let i = 0; i < this.body.supportNodeIndices.length; i++) {
  59. let supportNodeId = this.body.supportNodeIndices[i];
  60. if (this.body.edges[supportNodes[supportNodeId].parentEdgeId] !== undefined) {
  61. this.physicsBody.calculationNodes[supportNodeId] = supportNodes[supportNodeId];
  62. }
  63. else {
  64. console.error("Support node detected that does not have an edge!")
  65. }
  66. }
  67. this.physicsBody.calculationNodeIndices = Object.keys(this.physicsBody.calculationNodes);
  68. }
  69. step() {
  70. this.gravitySolver.solve();
  71. this.nodesSolver.solve();
  72. this.edgesSolver.solve();
  73. }
  74. }
  75. export {PhysicsEngine};