@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.
- package/build/meep.cjs +71 -30
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +71 -30
- package/package.json +1 -1
- package/src/core/{graph → geom/3d/topology}/build_face_graph_from_mesh.js +5 -5
- package/src/core/graph/Edge.js +10 -22
- package/src/core/graph/Edge.spec.js +35 -0
- package/src/core/graph/MultiNode.js +6 -7
- package/src/core/graph/coloring/colorizeGraphGreedy.spec.js +1 -1
- package/src/core/graph/layout/CircleLayout.js +6 -11
- package/src/core/graph/v2/Graph.js +43 -8
- package/src/core/graph/v2/NodeContainer.js +19 -2
- package/src/core/graph/EdgeDirection.js +0 -11
- package/src/core/graph/Graph.js +0 -565
package/build/meep.module.js
CHANGED
|
@@ -70583,10 +70583,19 @@ class Edge {
|
|
|
70583
70583
|
return this.first === node || this.second === node;
|
|
70584
70584
|
}
|
|
70585
70585
|
|
|
70586
|
+
/**
|
|
70587
|
+
*
|
|
70588
|
+
* @param {N} source
|
|
70589
|
+
* @param {N} target
|
|
70590
|
+
* @returns {boolean} True iff the edge contains both source and target and allows transition from source to target
|
|
70591
|
+
*/
|
|
70586
70592
|
validateTransition(source, target) {
|
|
70587
70593
|
const a = this.first;
|
|
70588
70594
|
const b = this.second;
|
|
70589
|
-
|
|
70595
|
+
|
|
70596
|
+
return (a === source && b === target && this.traversableForward())
|
|
70597
|
+
|| (b === source && a === target && this.traversableBackward())
|
|
70598
|
+
;
|
|
70590
70599
|
}
|
|
70591
70600
|
|
|
70592
70601
|
/**
|
|
@@ -70634,16 +70643,6 @@ class Edge {
|
|
|
70634
70643
|
|| (this.second === node && this.direction === EdgeDirectionType.Backward)
|
|
70635
70644
|
}
|
|
70636
70645
|
|
|
70637
|
-
/**
|
|
70638
|
-
* @deprecated
|
|
70639
|
-
* @returns {number}
|
|
70640
|
-
*/
|
|
70641
|
-
angle() {
|
|
70642
|
-
|
|
70643
|
-
const delta = this.second.clone().sub(this.first);
|
|
70644
|
-
return Math.atan2(delta.y, delta.x);
|
|
70645
|
-
}
|
|
70646
|
-
|
|
70647
70646
|
/**
|
|
70648
70647
|
*
|
|
70649
70648
|
* @returns {N[]}
|
|
@@ -70652,15 +70651,6 @@ class Edge {
|
|
|
70652
70651
|
return [this.first, this.second];
|
|
70653
70652
|
}
|
|
70654
70653
|
|
|
70655
|
-
|
|
70656
|
-
/**
|
|
70657
|
-
* @deprecated
|
|
70658
|
-
* @returns {number}
|
|
70659
|
-
*/
|
|
70660
|
-
get length() {
|
|
70661
|
-
|
|
70662
|
-
return this.first.distanceTo(this.second);
|
|
70663
|
-
}
|
|
70664
70654
|
}
|
|
70665
70655
|
|
|
70666
70656
|
/**
|
|
@@ -70691,10 +70681,19 @@ class NodeContainer {
|
|
|
70691
70681
|
/**
|
|
70692
70682
|
*
|
|
70693
70683
|
* @type {Map<N,number>}
|
|
70684
|
+
* Maps neighbour node to number of edges to that node from this one
|
|
70694
70685
|
* @private
|
|
70695
70686
|
*/
|
|
70696
70687
|
__neighbors = new Map();
|
|
70697
70688
|
|
|
70689
|
+
/**
|
|
70690
|
+
* NOTE: this method allocates memory internally
|
|
70691
|
+
* @returns {N[]}
|
|
70692
|
+
*/
|
|
70693
|
+
get neighbours() {
|
|
70694
|
+
return Array.from(this.__neighbors.keys());
|
|
70695
|
+
}
|
|
70696
|
+
|
|
70698
70697
|
/**
|
|
70699
70698
|
*
|
|
70700
70699
|
* @return {number}
|
|
@@ -70712,7 +70711,7 @@ class NodeContainer {
|
|
|
70712
70711
|
}
|
|
70713
70712
|
|
|
70714
70713
|
/**
|
|
70715
|
-
*
|
|
70714
|
+
* NOTE: this method allocates memory internally
|
|
70716
70715
|
* @returns {N[]}
|
|
70717
70716
|
*/
|
|
70718
70717
|
get inNodes() {
|
|
@@ -70720,7 +70719,7 @@ class NodeContainer {
|
|
|
70720
70719
|
}
|
|
70721
70720
|
|
|
70722
70721
|
/**
|
|
70723
|
-
*
|
|
70722
|
+
* NOTE: this method allocates memory internally
|
|
70724
70723
|
* @returns {N[]}
|
|
70725
70724
|
*/
|
|
70726
70725
|
get outNodes() {
|
|
@@ -70728,6 +70727,10 @@ class NodeContainer {
|
|
|
70728
70727
|
}
|
|
70729
70728
|
|
|
70730
70729
|
|
|
70730
|
+
/**
|
|
70731
|
+
* NOTE: this method allocates memory internally
|
|
70732
|
+
* @returns {Edge<N>[]}
|
|
70733
|
+
*/
|
|
70731
70734
|
get outEdges() {
|
|
70732
70735
|
/**
|
|
70733
70736
|
*
|
|
@@ -70740,6 +70743,10 @@ class NodeContainer {
|
|
|
70740
70743
|
return result;
|
|
70741
70744
|
}
|
|
70742
70745
|
|
|
70746
|
+
/**
|
|
70747
|
+
* NOTE: this method allocates memory internally
|
|
70748
|
+
* @returns {Edge<N>[]}
|
|
70749
|
+
*/
|
|
70743
70750
|
get inEdges() {
|
|
70744
70751
|
/**
|
|
70745
70752
|
*
|
|
@@ -71068,6 +71075,7 @@ class Graph {
|
|
|
71068
71075
|
/**
|
|
71069
71076
|
*
|
|
71070
71077
|
* @param {N} node
|
|
71078
|
+
* @returns {boolean}
|
|
71071
71079
|
*/
|
|
71072
71080
|
removeNode(node) {
|
|
71073
71081
|
|
|
@@ -71141,7 +71149,7 @@ class Graph {
|
|
|
71141
71149
|
}
|
|
71142
71150
|
|
|
71143
71151
|
/**
|
|
71144
|
-
*
|
|
71152
|
+
* Node degree is the number of attached edges
|
|
71145
71153
|
* @param {N} node
|
|
71146
71154
|
* @return {number}
|
|
71147
71155
|
*/
|
|
@@ -71155,6 +71163,14 @@ class Graph {
|
|
|
71155
71163
|
return container.getEdgeCount();
|
|
71156
71164
|
}
|
|
71157
71165
|
|
|
71166
|
+
/**
|
|
71167
|
+
*
|
|
71168
|
+
* @returns {N[]}
|
|
71169
|
+
*/
|
|
71170
|
+
get nodes() {
|
|
71171
|
+
return Array.from(this.getNodes());
|
|
71172
|
+
}
|
|
71173
|
+
|
|
71158
71174
|
/**
|
|
71159
71175
|
* Do not modify this set directly
|
|
71160
71176
|
* @return {Iterable<N>}
|
|
@@ -71175,13 +71191,18 @@ class Graph {
|
|
|
71175
71191
|
*
|
|
71176
71192
|
* @param {N} source
|
|
71177
71193
|
* @param {N} target
|
|
71178
|
-
* @param {EdgeDirectionType} [
|
|
71194
|
+
* @param {EdgeDirectionType} [direction] Undirected by default
|
|
71179
71195
|
* @returns {Edge<N>}
|
|
71180
71196
|
*/
|
|
71181
|
-
createEdge(
|
|
71197
|
+
createEdge(
|
|
71198
|
+
source,
|
|
71199
|
+
target,
|
|
71200
|
+
direction = EdgeDirectionType.Undirected
|
|
71201
|
+
) {
|
|
71202
|
+
|
|
71182
71203
|
const edge = new Edge(source, target);
|
|
71183
71204
|
|
|
71184
|
-
edge.direction =
|
|
71205
|
+
edge.direction = direction;
|
|
71185
71206
|
|
|
71186
71207
|
this.addEdge(edge);
|
|
71187
71208
|
|
|
@@ -71189,9 +71210,10 @@ class Graph {
|
|
|
71189
71210
|
}
|
|
71190
71211
|
|
|
71191
71212
|
/**
|
|
71192
|
-
*
|
|
71213
|
+
* Both nodes that the edge is attached to must be present
|
|
71193
71214
|
* @param {Edge<N>} edge
|
|
71194
|
-
* @returns {boolean}
|
|
71215
|
+
* @returns {boolean} true if edge was added, false if edge was already present
|
|
71216
|
+
* @throws if one or both nodes are not contained in the graph
|
|
71195
71217
|
*/
|
|
71196
71218
|
addEdge(edge) {
|
|
71197
71219
|
if (this.hasEdge(edge)) {
|
|
@@ -71360,6 +71382,21 @@ class Graph {
|
|
|
71360
71382
|
return edge_count;
|
|
71361
71383
|
}
|
|
71362
71384
|
|
|
71385
|
+
/**
|
|
71386
|
+
*
|
|
71387
|
+
* @param {N} node
|
|
71388
|
+
* @returns {N[]}
|
|
71389
|
+
*/
|
|
71390
|
+
getNeighbours(node) {
|
|
71391
|
+
const container = this.__nodes.get(node);
|
|
71392
|
+
|
|
71393
|
+
if (container === undefined) {
|
|
71394
|
+
return [];
|
|
71395
|
+
}
|
|
71396
|
+
|
|
71397
|
+
return container.neighbours;
|
|
71398
|
+
}
|
|
71399
|
+
|
|
71363
71400
|
/**
|
|
71364
71401
|
*
|
|
71365
71402
|
* @param {N} node
|
|
@@ -71378,10 +71415,10 @@ class Graph {
|
|
|
71378
71415
|
}
|
|
71379
71416
|
|
|
71380
71417
|
/**
|
|
71381
|
-
*
|
|
71418
|
+
* Find a path through the graph
|
|
71382
71419
|
* @param {N} start
|
|
71383
71420
|
* @param {N} goal
|
|
71384
|
-
* @returns {null|N[]}
|
|
71421
|
+
* @returns {null|N[]} null if no path exists
|
|
71385
71422
|
*/
|
|
71386
71423
|
findPath(start, goal) {
|
|
71387
71424
|
const start_node_container = this.__nodes.get(start);
|
|
@@ -71421,6 +71458,7 @@ class Graph {
|
|
|
71421
71458
|
const b = edge.second;
|
|
71422
71459
|
|
|
71423
71460
|
let other = null;
|
|
71461
|
+
|
|
71424
71462
|
if (a === current_node && (edge.direction === EdgeDirectionType.Forward || edge.direction === EdgeDirectionType.Undirected)) {
|
|
71425
71463
|
other = b;
|
|
71426
71464
|
} else if (b === current_node && (edge.direction === EdgeDirectionType.Backward || edge.direction === EdgeDirectionType.Undirected)) {
|
|
@@ -71449,6 +71487,9 @@ class Graph {
|
|
|
71449
71487
|
return null;
|
|
71450
71488
|
}
|
|
71451
71489
|
|
|
71490
|
+
/**
|
|
71491
|
+
* Remove all data from the graph, resetting it to empty state
|
|
71492
|
+
*/
|
|
71452
71493
|
clear() {
|
|
71453
71494
|
this.__nodes.clear();
|
|
71454
71495
|
this.__edges.clear();
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { MultiNode } from "
|
|
3
|
-
import {
|
|
4
|
-
import { WeightedEdge } from "
|
|
5
|
-
import {
|
|
1
|
+
import { graph_compute_disconnected_clusters } from "../../../graph/graph_compute_disconnected_clusters.js";
|
|
2
|
+
import { MultiNode } from "../../../graph/MultiNode.js";
|
|
3
|
+
import { Graph } from "../../../graph/v2/Graph.js";
|
|
4
|
+
import { WeightedEdge } from "../../../graph/WeightedEdge.js";
|
|
5
|
+
import { compute_face_connection_weight } from "./util/compute_face_connection_weight.js";
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
/**
|
package/src/core/graph/Edge.js
CHANGED
|
@@ -55,10 +55,19 @@ export class Edge {
|
|
|
55
55
|
return this.first === node || this.second === node;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @param {N} source
|
|
61
|
+
* @param {N} target
|
|
62
|
+
* @returns {boolean} True iff the edge contains both source and target and allows transition from source to target
|
|
63
|
+
*/
|
|
58
64
|
validateTransition(source, target) {
|
|
59
65
|
const a = this.first;
|
|
60
66
|
const b = this.second;
|
|
61
|
-
|
|
67
|
+
|
|
68
|
+
return (a === source && b === target && this.traversableForward())
|
|
69
|
+
|| (b === source && a === target && this.traversableBackward())
|
|
70
|
+
;
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
/**
|
|
@@ -106,17 +115,6 @@ export class Edge {
|
|
|
106
115
|
|| (this.second === node && this.direction === EdgeDirectionType.Backward)
|
|
107
116
|
}
|
|
108
117
|
|
|
109
|
-
/**
|
|
110
|
-
* @deprecated
|
|
111
|
-
* @returns {number}
|
|
112
|
-
*/
|
|
113
|
-
angle() {
|
|
114
|
-
console.error('method is deprecated, do not use');
|
|
115
|
-
|
|
116
|
-
const delta = this.second.clone().sub(this.first);
|
|
117
|
-
return Math.atan2(delta.y, delta.x);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
118
|
/**
|
|
121
119
|
*
|
|
122
120
|
* @returns {N[]}
|
|
@@ -125,16 +123,6 @@ export class Edge {
|
|
|
125
123
|
return [this.first, this.second];
|
|
126
124
|
}
|
|
127
125
|
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* @deprecated
|
|
131
|
-
* @returns {number}
|
|
132
|
-
*/
|
|
133
|
-
get length() {
|
|
134
|
-
console.error('method is deprecated, do not use');
|
|
135
|
-
|
|
136
|
-
return this.first.distanceTo(this.second);
|
|
137
|
-
}
|
|
138
126
|
}
|
|
139
127
|
|
|
140
128
|
/**
|
|
@@ -48,3 +48,38 @@ test('other', () => {
|
|
|
48
48
|
expect(edge.other(3)).toBe(7);
|
|
49
49
|
expect(edge.other(7)).toBe(3);
|
|
50
50
|
});
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
test("isDirectedTowards", () => {
|
|
54
|
+
const e = new Edge(1, 3);
|
|
55
|
+
|
|
56
|
+
e.direction = EdgeDirectionType.Forward;
|
|
57
|
+
|
|
58
|
+
expect(e.isDirectedTowards(3)).toBe(true);
|
|
59
|
+
expect(e.isDirectedTowards(1)).toBe(false);
|
|
60
|
+
|
|
61
|
+
e.direction = EdgeDirectionType.Backward;
|
|
62
|
+
|
|
63
|
+
expect(e.isDirectedTowards(3)).toBe(false);
|
|
64
|
+
expect(e.isDirectedTowards(1)).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("isDirectedAwayFrom", () => {
|
|
68
|
+
const e = new Edge(1, 3);
|
|
69
|
+
|
|
70
|
+
e.direction = EdgeDirectionType.Forward;
|
|
71
|
+
|
|
72
|
+
expect(e.isDirectedAwayFrom(3)).toBe(false);
|
|
73
|
+
expect(e.isDirectedAwayFrom(1)).toBe(true);
|
|
74
|
+
|
|
75
|
+
e.direction = EdgeDirectionType.Backward;
|
|
76
|
+
|
|
77
|
+
expect(e.isDirectedAwayFrom(3)).toBe(true);
|
|
78
|
+
expect(e.isDirectedAwayFrom(1)).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("nodes accessor", () => {
|
|
82
|
+
const e = new Edge(1, 3);
|
|
83
|
+
|
|
84
|
+
expect(e.nodes).toEqual([1, 3]);
|
|
85
|
+
});
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* A grouping node, intended mainly for meta-graphs, or hierarchical graphs
|
|
2
3
|
* @template T
|
|
3
4
|
*/
|
|
4
5
|
export class MultiNode {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this.source_nodes = [];
|
|
11
|
-
}
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @type {T[]}
|
|
9
|
+
*/
|
|
10
|
+
source_nodes = [];
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
*
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {Array.<Circle>} input
|
|
4
|
-
* @param {Graph} graph
|
|
5
|
-
*/
|
|
6
1
|
import { assert } from "../../assert.js";
|
|
7
|
-
import Circle from "../../geom/2d/circle/Circle.js";
|
|
8
2
|
import AABB2 from "../../geom/2d/aabb/AABB2.js";
|
|
3
|
+
import Circle from "../../geom/2d/circle/Circle.js";
|
|
4
|
+
import {
|
|
5
|
+
line_segment_line_segment_intersection_exists_2d
|
|
6
|
+
} from "../../geom/2d/line/line_segment_line_segment_intersection_exists_2d.js";
|
|
9
7
|
import Vector2, { v2_distance } from "../../geom/Vector2.js";
|
|
10
8
|
import { max2 } from "../../math/max2.js";
|
|
11
9
|
import { min2 } from "../../math/min2.js";
|
|
10
|
+
import { applyCentralGravityAABB2 } from "./box/applyCentralGravityAABB2.js";
|
|
11
|
+
import { resolveAABB2Overlap } from "./box/resolveAABB2Overlap.js";
|
|
12
12
|
import { computeDisconnectedSubGraphs } from "./computeDisconnectedSubGraphs.js";
|
|
13
13
|
import { Connection } from "./Connection.js";
|
|
14
|
-
import { resolveAABB2Overlap } from "./box/resolveAABB2Overlap.js";
|
|
15
|
-
import { applyCentralGravityAABB2 } from "./box/applyCentralGravityAABB2.js";
|
|
16
|
-
import {
|
|
17
|
-
line_segment_line_segment_intersection_exists_2d
|
|
18
|
-
} from "../../geom/2d/line/line_segment_line_segment_intersection_exists_2d.js";
|
|
19
14
|
|
|
20
15
|
|
|
21
16
|
/**
|
|
@@ -92,6 +92,7 @@ export class Graph {
|
|
|
92
92
|
/**
|
|
93
93
|
*
|
|
94
94
|
* @param {N} node
|
|
95
|
+
* @returns {boolean}
|
|
95
96
|
*/
|
|
96
97
|
removeNode(node) {
|
|
97
98
|
|
|
@@ -165,7 +166,7 @@ export class Graph {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
/**
|
|
168
|
-
*
|
|
169
|
+
* Node degree is the number of attached edges
|
|
169
170
|
* @param {N} node
|
|
170
171
|
* @return {number}
|
|
171
172
|
*/
|
|
@@ -179,6 +180,14 @@ export class Graph {
|
|
|
179
180
|
return container.getEdgeCount();
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
/**
|
|
184
|
+
*
|
|
185
|
+
* @returns {N[]}
|
|
186
|
+
*/
|
|
187
|
+
get nodes() {
|
|
188
|
+
return Array.from(this.getNodes());
|
|
189
|
+
}
|
|
190
|
+
|
|
182
191
|
/**
|
|
183
192
|
* Do not modify this set directly
|
|
184
193
|
* @return {Iterable<N>}
|
|
@@ -199,13 +208,19 @@ export class Graph {
|
|
|
199
208
|
*
|
|
200
209
|
* @param {N} source
|
|
201
210
|
* @param {N} target
|
|
202
|
-
* @param {EdgeDirectionType} [
|
|
211
|
+
* @param {EdgeDirectionType} [direction] Undirected by default
|
|
203
212
|
* @returns {Edge<N>}
|
|
204
213
|
*/
|
|
205
|
-
createEdge(
|
|
214
|
+
createEdge(
|
|
215
|
+
source,
|
|
216
|
+
target,
|
|
217
|
+
direction = EdgeDirectionType.Undirected
|
|
218
|
+
) {
|
|
219
|
+
assert.enum(direction, EdgeDirectionType, 'direction');
|
|
220
|
+
|
|
206
221
|
const edge = new Edge(source, target);
|
|
207
222
|
|
|
208
|
-
edge.direction =
|
|
223
|
+
edge.direction = direction;
|
|
209
224
|
|
|
210
225
|
this.addEdge(edge);
|
|
211
226
|
|
|
@@ -213,9 +228,10 @@ export class Graph {
|
|
|
213
228
|
}
|
|
214
229
|
|
|
215
230
|
/**
|
|
216
|
-
*
|
|
231
|
+
* Both nodes that the edge is attached to must be present
|
|
217
232
|
* @param {Edge<N>} edge
|
|
218
|
-
* @returns {boolean}
|
|
233
|
+
* @returns {boolean} true if edge was added, false if edge was already present
|
|
234
|
+
* @throws if one or both nodes are not contained in the graph
|
|
219
235
|
*/
|
|
220
236
|
addEdge(edge) {
|
|
221
237
|
if (this.hasEdge(edge)) {
|
|
@@ -390,6 +406,21 @@ export class Graph {
|
|
|
390
406
|
return edge_count;
|
|
391
407
|
}
|
|
392
408
|
|
|
409
|
+
/**
|
|
410
|
+
*
|
|
411
|
+
* @param {N} node
|
|
412
|
+
* @returns {N[]}
|
|
413
|
+
*/
|
|
414
|
+
getNeighbours(node) {
|
|
415
|
+
const container = this.__nodes.get(node);
|
|
416
|
+
|
|
417
|
+
if (container === undefined) {
|
|
418
|
+
return [];
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return container.neighbours;
|
|
422
|
+
}
|
|
423
|
+
|
|
393
424
|
/**
|
|
394
425
|
*
|
|
395
426
|
* @param {N} node
|
|
@@ -408,10 +439,10 @@ export class Graph {
|
|
|
408
439
|
}
|
|
409
440
|
|
|
410
441
|
/**
|
|
411
|
-
*
|
|
442
|
+
* Find a path through the graph
|
|
412
443
|
* @param {N} start
|
|
413
444
|
* @param {N} goal
|
|
414
|
-
* @returns {null|N[]}
|
|
445
|
+
* @returns {null|N[]} null if no path exists
|
|
415
446
|
*/
|
|
416
447
|
findPath(start, goal) {
|
|
417
448
|
const start_node_container = this.__nodes.get(start);
|
|
@@ -451,6 +482,7 @@ export class Graph {
|
|
|
451
482
|
const b = edge.second;
|
|
452
483
|
|
|
453
484
|
let other = null;
|
|
485
|
+
|
|
454
486
|
if (a === current_node && (edge.direction === EdgeDirectionType.Forward || edge.direction === EdgeDirectionType.Undirected)) {
|
|
455
487
|
other = b;
|
|
456
488
|
} else if (b === current_node && (edge.direction === EdgeDirectionType.Backward || edge.direction === EdgeDirectionType.Undirected)) {
|
|
@@ -479,6 +511,9 @@ export class Graph {
|
|
|
479
511
|
return null;
|
|
480
512
|
}
|
|
481
513
|
|
|
514
|
+
/**
|
|
515
|
+
* Remove all data from the graph, resetting it to empty state
|
|
516
|
+
*/
|
|
482
517
|
clear() {
|
|
483
518
|
this.__nodes.clear();
|
|
484
519
|
this.__edges.clear();
|
|
@@ -22,10 +22,19 @@ export class NodeContainer {
|
|
|
22
22
|
/**
|
|
23
23
|
*
|
|
24
24
|
* @type {Map<N,number>}
|
|
25
|
+
* Maps neighbour node to number of edges to that node from this one
|
|
25
26
|
* @private
|
|
26
27
|
*/
|
|
27
28
|
__neighbors = new Map();
|
|
28
29
|
|
|
30
|
+
/**
|
|
31
|
+
* NOTE: this method allocates memory internally
|
|
32
|
+
* @returns {N[]}
|
|
33
|
+
*/
|
|
34
|
+
get neighbours() {
|
|
35
|
+
return Array.from(this.__neighbors.keys());
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
/**
|
|
30
39
|
*
|
|
31
40
|
* @return {number}
|
|
@@ -43,7 +52,7 @@ export class NodeContainer {
|
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
/**
|
|
46
|
-
*
|
|
55
|
+
* NOTE: this method allocates memory internally
|
|
47
56
|
* @returns {N[]}
|
|
48
57
|
*/
|
|
49
58
|
get inNodes() {
|
|
@@ -51,7 +60,7 @@ export class NodeContainer {
|
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
/**
|
|
54
|
-
*
|
|
63
|
+
* NOTE: this method allocates memory internally
|
|
55
64
|
* @returns {N[]}
|
|
56
65
|
*/
|
|
57
66
|
get outNodes() {
|
|
@@ -59,6 +68,10 @@ export class NodeContainer {
|
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
|
|
71
|
+
/**
|
|
72
|
+
* NOTE: this method allocates memory internally
|
|
73
|
+
* @returns {Edge<N>[]}
|
|
74
|
+
*/
|
|
62
75
|
get outEdges() {
|
|
63
76
|
/**
|
|
64
77
|
*
|
|
@@ -71,6 +84,10 @@ export class NodeContainer {
|
|
|
71
84
|
return result;
|
|
72
85
|
}
|
|
73
86
|
|
|
87
|
+
/**
|
|
88
|
+
* NOTE: this method allocates memory internally
|
|
89
|
+
* @returns {Edge<N>[]}
|
|
90
|
+
*/
|
|
74
91
|
get inEdges() {
|
|
75
92
|
/**
|
|
76
93
|
*
|