@woosh/meep-engine 2.77.0 → 2.78.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,565 +0,0 @@
1
- /**
2
- * Created by Alex on 29/01/14.
3
- */
4
-
5
-
6
- import Signal from "../events/signal/Signal.js";
7
- import { Edge, EdgeDirectionType } from "./Edge.js";
8
-
9
- /**
10
- * @callback Graph~visitor
11
- * @param {*} node
12
- * @param {Edge} edge
13
- * @returns {boolean|undefined} if false is returned, traversal should stop
14
- */
15
-
16
- /**
17
- * @template N
18
- * @deprecated use v2 `Graph` class instead, it's faster and has a wider range of algorithms built on top of it
19
- */
20
- export class Graph {
21
- /**
22
- * @template N
23
- * @constructor
24
- */
25
- constructor() {
26
- /**
27
- * @private
28
- * @type {N[]}
29
- */
30
- this.__nodes = [];
31
-
32
- /**
33
- * Accelerated data structure for faster lookups
34
- * @type {Set<any>}
35
- * @private
36
- */
37
- this.__nodes_set = new Set();
38
-
39
- /**
40
- * @private
41
- * @type {Edge<N>[]}
42
- */
43
- this.__edges = [];
44
- this.onChange = new Signal();
45
- }
46
-
47
- /**
48
- *
49
- * @returns {N[]}
50
- */
51
- get nodes() {
52
- return this.__nodes;
53
- }
54
-
55
- /**
56
- *
57
- * @returns {Edge<N>[]}
58
- */
59
- get edges() {
60
- return this.__edges;
61
- }
62
-
63
- /**
64
- * Converts this graph into a shallow copy of supplied graph
65
- * @param {Graph<N>} other
66
- */
67
- copy(other) {
68
- this.clear();
69
-
70
- this.__nodes = other.__nodes.slice();
71
- this.__edges = other.__edges.slice();
72
-
73
- this.__nodes_set = new Set(this.__nodes);
74
- }
75
-
76
- /**
77
- *
78
- * @param {N} start
79
- * @param {N} goal
80
- * @returns {Array<N>|null} nodes from start to goal in the shortest path including both start and goal.
81
- */
82
- findPath(start, goal) {
83
- const open = new Set();
84
- open.add(start);
85
-
86
- const closed = new Set();
87
-
88
- const cameFrom = new Map();
89
-
90
- function constructPath() {
91
- const result = [];
92
- let c = goal;
93
- do {
94
- result.unshift(c);
95
- c = cameFrom.get(c);
96
- } while (c !== undefined);
97
-
98
- return result;
99
- }
100
-
101
- const graph = this;
102
-
103
- function expandNode(current) {
104
- graph.traverseSuccessors(current, function (node, edge) {
105
- if (closed.has(node)) {
106
- return;
107
- }
108
- if (open.has(node)) {
109
- return;
110
- }
111
- open.add(node);
112
- cameFrom.set(node, current);
113
- });
114
- }
115
-
116
- while (open.size > 0) {
117
- const current = open.values().next().value;
118
- if (current === goal) {
119
- //reached the goal
120
- return constructPath();
121
- }
122
- open.delete(current);
123
- closed.add(current);
124
-
125
- //expand node
126
- expandNode(current);
127
- }
128
-
129
- //no path found
130
- return null;
131
- }
132
-
133
- /**
134
- * Returns true if there is an edge between two given nodes on this graph
135
- * @param {N} node1
136
- * @param {N} node2
137
- * @returns {boolean}
138
- */
139
- isEdgeBetween(node1, node2) {
140
- if (!this.containsNode(node1) || !this.containsNode(node2)) {
141
- return false; // one or both nodes are not part of the graph
142
- }
143
- const connectingEdge = this.findConnectingEdge(node1, node2);
144
- return connectingEdge !== null;
145
- }
146
-
147
- /**
148
- * Strictly traversable edge exists from source to target
149
- * @param {N} source
150
- * @param {N} target
151
- * @returns {boolean}
152
- */
153
- edgeExists(source, target) {
154
- if (!this.containsNode(source) || !this.containsNode(target)) {
155
- return false; // one or both nodes are not part of the graph
156
- }
157
-
158
- return this.traversePredecessors(source, function (destination) {
159
- if (destination === target) {
160
- //terminate traversal, this will make "traversePredecessors" return true also
161
- return false;
162
- }
163
- });
164
- }
165
-
166
- /**
167
- *
168
- * @param {function(node:N):boolean} visitor
169
- * @param {*} [thisArg]
170
- */
171
- traverseNodes(visitor, thisArg) {
172
- const nodes = this.__nodes;
173
- const l = nodes.length;
174
- for (let i = 0; i < l; i++) {
175
- const node = nodes[i];
176
- if (visitor.call(thisArg, node) === false) {
177
- return;
178
- }
179
- }
180
- }
181
-
182
- /**
183
- *
184
- * @param {N} node
185
- * @param {function(node:N, edge:Edge<N>):(boolean|void)} visitor
186
- */
187
- traverseSuccessors(node, visitor) {
188
- const edges = this.__edges;
189
- let i = 0;
190
- const l = edges.length;
191
-
192
- for (; i < l; i++) {
193
- const edge = edges[i];
194
- const first = edge.first;
195
- const second = edge.second;
196
-
197
- if (first === node && edge.traversableForward()) {
198
- if (visitor(second, edge) === false) {
199
- //terminate traversal if visitor returns false
200
- return;
201
- }
202
- } else if (second === node && edge.traversableBackward()) {
203
- if (visitor(first, edge) === false) {
204
- //terminate traversal if visitor returns false
205
- return;
206
- }
207
- }
208
- }
209
-
210
- }
211
-
212
- /**
213
- *
214
- * @param {function(edge:Edge<N>):boolean} visitor
215
- */
216
- traverseEdges(visitor) {
217
- const edges = this.__edges;
218
- let i = 0;
219
- const l = edges.length;
220
- for (; i < l; i++) {
221
- const edge = edges[i];
222
- if (visitor(edge) === false) {
223
- //terminate traversal if visitor returns false
224
- return;
225
- }
226
- }
227
- }
228
-
229
- /**
230
- *
231
- * @param {N} node
232
- * @param {function(N,Edge<N>)} visitor
233
- */
234
- traversePredecessors(node, visitor) {
235
- const edges = this.__edges;
236
- let i = 0;
237
- const l = edges.length;
238
- for (; i < l; i++) {
239
- const edge = edges[i];
240
- const first = edge.first;
241
- const second = edge.second;
242
-
243
- if (second === node && edge.traversableForward()) {
244
- if (visitor(first, edge) === false) {
245
- //terminate traversal if visitor returns false
246
- return true;
247
- }
248
- } else if (first === node && edge.traversableBackward()) {
249
- if (visitor(second, edge) === false) {
250
- //terminate traversal if visitor returns false
251
- return true;
252
- }
253
- }
254
- }
255
- return false;
256
- }
257
-
258
- /**
259
- *
260
- * @param {N} node
261
- * @param {function(N,Edge):(boolean|void)} visitor
262
- */
263
- traverseAttachedEdges(node, visitor) {
264
- const edges = this.__edges;
265
- let i = 0;
266
- const l = edges.length;
267
- for (; i < l; i++) {
268
- const edge = edges[i];
269
- const first = edge.first;
270
- const second = edge.second;
271
-
272
- if (first === node) {
273
- if (visitor(second, edge) === false) {
274
- //terminate traversal if visitor returns false
275
- return;
276
- }
277
- } else if (second === node) {
278
- if (visitor(first, edge) === false) {
279
- //terminate traversal if visitor returns false
280
- return;
281
- }
282
- }
283
- }
284
- }
285
-
286
- /**
287
- *
288
- * @param {N} source
289
- * @param {N} target
290
- * @return {Edge<N>|null}
291
- */
292
- findTraversableEdge(source, target) {
293
-
294
- const edges = this.__edges;
295
-
296
- const numEdges = edges.length;
297
-
298
- for (let i = 0; i < numEdges; i++) {
299
-
300
- /**
301
- *
302
- * @type {Edge<N>}
303
- */
304
- const edge = edges[i];
305
-
306
- if (
307
- (edge.first === source && edge.second === target && edge.direction !== EdgeDirectionType.Backward)
308
- || (edge.second === source && edge.first === target && edge.direction !== EdgeDirectionType.Forward)
309
- ) {
310
- return edge;
311
- }
312
- }
313
-
314
- return null;
315
- }
316
-
317
- /**
318
- *
319
- * @param {N} node1
320
- * @param {N} node2
321
- * @returns {Edge<N>|null}
322
- */
323
- findConnectingEdge(node1, node2) {
324
- const edges = this.__edges;
325
-
326
- const numEdges = edges.length;
327
-
328
- for (let i = 0; i < numEdges; i++) {
329
-
330
- const edge = edges[i];
331
-
332
- if (edge.contains(node1) && edge.contains(node2)) {
333
- return edge;
334
- }
335
-
336
- }
337
-
338
- return null;
339
- }
340
-
341
- /**
342
- *
343
- * @param {N} source
344
- * @param {N} target
345
- * @param {function(Edge<N>):boolean} visitor
346
- */
347
- findTraversableEdges(source, target, visitor) {
348
- const edges = this.__edges;
349
- for (let i = 0; i < edges.length; i++) {
350
- const edge = edges[i];
351
- if (edge.validateTransition(source, target)) {
352
-
353
- if (visitor(edge) === false) {
354
- return;
355
- }
356
- }
357
- }
358
- }
359
-
360
- /**
361
- *
362
- * @param {N} node
363
- * @returns {Edge<N>[]}
364
- */
365
- getAttachedEdges(node) {
366
- let i = 0;
367
-
368
- const result = [];
369
-
370
- const edges = this.__edges;
371
- const l = edges.length;
372
-
373
- for (; i < l; i++) {
374
- const edge = edges[i];
375
-
376
- if (edge.contains(node)) {
377
- result.push(edge);
378
- }
379
- }
380
-
381
- return result;
382
- }
383
-
384
- /**
385
- *
386
- * @param {N} node
387
- * @returns {N[]}
388
- */
389
- getNeighbours(node) {
390
- const result = [];
391
-
392
- const edges = this.edges;
393
- const nEdges = edges.length;
394
-
395
- for (let i = 0; i < nEdges; i++) {
396
- const edge = edges[i];
397
-
398
- const first = edge.first;
399
- const second = edge.second;
400
-
401
- if (first === node && (edge.direction === EdgeDirectionType.Forward || edge.direction === EdgeDirectionType.Undirected)) {
402
- if (result.indexOf(second) === -1) {
403
- result.push(second);
404
- }
405
- } else if (second === node && (edge.direction === EdgeDirectionType.Backward || edge.direction === EdgeDirectionType.Undirected)) {
406
- if (result.indexOf(first) === -1) {
407
- result.push(first);
408
- }
409
- }
410
-
411
- }
412
-
413
- return result;
414
- }
415
-
416
- /**
417
- *
418
- * @param {N} node
419
- * @returns {boolean}
420
- */
421
- containsNode(node) {
422
- return this.__nodes_set.has(node);
423
- }
424
-
425
- /**
426
- * @deprecated
427
- * @returns {number}
428
- */
429
- length() {
430
- const edges = this.__edges;
431
- let result = 0;
432
- for (let i = 0; i < edges.length; i++) {
433
- const edge = edges[i];
434
- result += edge.length;
435
- }
436
- return result;
437
- }
438
-
439
- /**
440
- *
441
- * @param {N} node
442
- */
443
- addNode(node) {
444
-
445
- this.__nodes_set.add(node);
446
-
447
- this.__nodes.push(node);
448
- }
449
-
450
- /**
451
- *
452
- * @param {N} node
453
- * @returns {boolean}
454
- */
455
- removeNode(node) {
456
- if (!this.containsNode(node)) {
457
- return false;
458
- }
459
-
460
- const i = this.__nodes.indexOf(node);
461
-
462
- if (i === -1) {
463
- // this should never happen
464
- return false;
465
- } else {
466
- //remove attached connections
467
- const attachedEdges = this.getAttachedEdges(node);
468
-
469
- const n = attachedEdges.length;
470
-
471
- for (let j = 0; j < n; j++) {
472
- const edge = attachedEdges[j];
473
-
474
- this.removeEdge(edge);
475
- }
476
-
477
- this.__nodes.splice(i, 1);
478
- this.__nodes_set.delete(node);
479
-
480
- return true;
481
- }
482
- }
483
-
484
- /**
485
- * Whether or not the graph contains given node
486
- * NOTE: same as {@link #containsNode}
487
- * @param {N} node
488
- * @returns {boolean}
489
- */
490
- hasNode(node) {
491
- return this.containsNode(node);
492
- }
493
-
494
- /**
495
- *
496
- * @param {Edge<N>} edge
497
- */
498
- addEdge(edge) {
499
- //assert.ok(this.containsNode(edge.first), `Node Edge.first(=${edge.first}) is not present in the graph`);
500
- //assert.ok(this.containsNode(edge.second), `Node Edge.second(=${edge.second}) is not present in the graph`);
501
-
502
- this.__edges.push(edge);
503
- this.onChange.send1(edge);
504
- }
505
-
506
- /**
507
- *
508
- * @param {N} source
509
- * @param {N} target
510
- * @param {EdgeDirectionType} [direction]
511
- * @returns {Edge<N>}
512
- */
513
- createEdge(source, target, direction = EdgeDirectionType.Undirected) {
514
- const edge = new Edge(source, target);
515
-
516
- edge.direction = direction;
517
-
518
- this.addEdge(edge);
519
-
520
- return edge;
521
- }
522
-
523
- /**
524
- *
525
- * @param {Edge<N>} edge
526
- * @returns {boolean}
527
- */
528
- removeEdge(edge) {
529
- const edges = this.__edges;
530
- const indexOf = edges.indexOf(edge);
531
- if (indexOf >= 0) {
532
- edges.splice(indexOf, 1);
533
- this.onChange.send1(edge);
534
-
535
- return true;
536
- } else {
537
- console.error("Edge was not found");
538
-
539
- return false;
540
- }
541
- }
542
-
543
- clear() {
544
- this.__edges = [];
545
- this.__nodes = [];
546
- this.__nodes_set.clear();
547
-
548
- this.onChange.send0();
549
- }
550
-
551
- /**
552
- *
553
- * @returns {Graph<N>}
554
- */
555
- clone() {
556
- const graph = new Graph();
557
-
558
- graph.copy(this);
559
-
560
- return graph;
561
- }
562
- }
563
-
564
-
565
- export default Graph;