paths.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. var PathSet = function(options) {
  2. var defaults = {
  3. nodes: [],
  4. edges: Object.create(null), // indexed by "from" node
  5. nodeTypes: Object.create(null),
  6. nodeRefs: Object.create(null),
  7. nodeMatchEpsilon: .5,
  8. };
  9. var e = $.extend({}, defaults, options);
  10. for(x in e) this[x] = e[x];
  11. // shorthand
  12. this.c = this.components;
  13. this.init();
  14. };
  15. PathSet.prototype.init = function() {
  16. };
  17. // returns the new node id
  18. PathSet.prototype.addNode = function(pos, type, ref) {
  19. var e = this.nodeMatchEpsilon;
  20. type = type || null;
  21. ref = ref || null;
  22. // look for an existing node that's close enough
  23. for(var i = 0; i < this.nodes.length; i++) {
  24. var n = this.nodes[i];
  25. if(pos.x + e >= n.x
  26. && pos.x - e < n.x
  27. && pos.y + e >= n.y
  28. && pos.y - e < n.y) {
  29. // update the metadata
  30. if(null !== type) this.nodeTypes[i] = type;
  31. if(null !== ref) this.nodeRefs[i] = ref;
  32. return i;
  33. }
  34. }
  35. // no match has been found, insert a new one
  36. var ind = this.nodes.length;
  37. this.nodes.push(ptc(pos));
  38. this.edges[ind] = [];
  39. this.nodeTypes[ind] = type;
  40. this.nodeRefs[ind] = ref;
  41. return ind;
  42. };
  43. PathSet.prototype.addNodeIntoEdge = function(pos, type, ref) {
  44. var n = this.addNode(pos, type, ref);
  45. // check all paths
  46. }
  47. // adds an edge between two nodes
  48. PathSet.prototype.addEdge = function(from, to, bidirectional) {
  49. if(-1 === this.edges[from].indexOf(to))
  50. this.edges[from].push(to);
  51. if(bidirectional && -1 === this.edges[to].indexOf(from))
  52. this.edges[to].push(from);
  53. };
  54. // adds a path between two points
  55. PathSet.prototype.addPath = function(from, to, bidirectional) {
  56. var f = this.addNode(from);
  57. var t = this.addNode(to);
  58. return this.addEdge(f, t, bidirectional);
  59. };
  60. PathSet.prototype.directConnected = function(from, to) {
  61. return this.edges[from].indexOf(to) !== -1;
  62. }
  63. PathSet.prototype.getNodeNear = function(pos, e) {
  64. e = e || this.nodeMatchEpsilon;
  65. // look for an existing node that's close enough
  66. for(var i = 0; i < this.nodes.length; i++) {
  67. var n = this.nodes[i];
  68. if(pos.x + e >= n.x
  69. && pos.x - e < n.x
  70. && pos.y + e >= n.y
  71. && pos.y - e < n.y) {
  72. return i;
  73. }
  74. }
  75. return null;
  76. };
  77. PathSet.prototype.followRandomEdge = function(node) {
  78. var edges = this.edges[node];
  79. if(!edges) return null; // bad node or no exits
  80. var i = rand(0, edges.length - 1);
  81. return ptc(this.nodes[edges[i]]);
  82. };
  83. PathSet.prototype.followTowardsDrink = function(node) {
  84. var edges = this.edges[node];
  85. if(!edges) return null; // bad node or no exits
  86. var i = rand(0, edges.length - 1);
  87. return ptc(this.nodes[edges[i]]);
  88. };