@woosh/meep-engine 2.76.4 → 2.78.0
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 +236 -616
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +236 -616
- package/editor/view/ecs/components/TerrainController.js +9 -16
- package/package.json +1 -1
- package/src/core/collection/heap/Uint32Heap.js +10 -1
- package/src/core/graph/Edge.js +20 -0
- package/src/core/graph/SquareMatrix.js +4 -2
- package/src/core/graph/WeightedEdge.js +5 -9
- package/src/core/graph/coloring/colorizeGraphGreedy.spec.js +1 -1
- package/src/core/graph/coloring/validateGraphColoring.js +1 -1
- package/src/core/graph/eigen/matrix_eigenvalues_in_place.js +21 -0
- package/src/core/graph/eigen/{eigen.spec.js → matrix_eigenvalues_in_place.spec.js} +2 -2
- package/src/core/graph/eigen/matrix_householder_in_place.js +92 -0
- package/src/core/graph/eigen/{eigen.js → matrix_qr_in_place.js} +2 -113
- package/src/core/graph/layout/CircleLayout.js +6 -11
- package/src/core/graph/v2/Graph.js +39 -9
- package/src/core/graph/v2/NodeContainer.js +136 -22
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +8 -6
- package/src/engine/graphics/particles/node-based/codegen/modules/FunctionModuleRegistry.js +1 -1
- package/src/engine/navigation/grid/find_path_on_grid_astar.js +25 -22
- package/src/engine/navigation/grid/find_path_on_grid_astar.spec.js +2 -2
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +17 -33
- package/src/core/graph/Graph.js +0 -564
- package/src/core/graph/GraphUtils.js +0 -284
- package/src/engine/ecs/terrain/ecs/splat/SplatMapMaterialPatch.js +0 -464
- package/src/engine/ecs/terrain/ecs/splat/SplatMapOptimizer.js +0 -622
- package/src/engine/ecs/terrain/ecs/splat/SplatMapOptimizerDebugger.js +0 -383
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Signal from "../../../../src/core/events/signal/Signal.js";
|
|
2
2
|
import Vector2 from "../../../../src/core/geom/Vector2.js";
|
|
3
|
-
import
|
|
4
|
-
import { NativeListController } from "../../../../src/view/controller/controls/NativeListController.js";
|
|
3
|
+
import ObservedValue from "../../../../src/core/model/ObservedValue.js";
|
|
5
4
|
import { TerrainLayer } from "../../../../src/engine/ecs/terrain/ecs/layers/TerrainLayer.js";
|
|
6
5
|
import CheckersTextureURI from "../../../../src/engine/graphics/texture/CheckersTextureURI.js";
|
|
7
|
-
import EmptyView from "../../../../src/view/elements/EmptyView.js";
|
|
8
|
-
import convertSampler2D2Canvas from "../../../../src/engine/graphics/texture/sampler/Sampler2D2Canvas.js";
|
|
9
|
-
import { CanvasView } from "../../../../src/view/elements/CanvasView.js";
|
|
10
6
|
import { sampler2d_scale } from "../../../../src/engine/graphics/texture/sampler/resize/sampler2d_scale.js";
|
|
11
7
|
import { Sampler2D } from "../../../../src/engine/graphics/texture/sampler/Sampler2D.js";
|
|
12
|
-
import
|
|
8
|
+
import convertSampler2D2Canvas from "../../../../src/engine/graphics/texture/sampler/Sampler2D2Canvas.js";
|
|
9
|
+
import LabelView from "../../../../src/view/common/LabelView.js";
|
|
10
|
+
import { NativeListController } from "../../../../src/view/controller/controls/NativeListController.js";
|
|
13
11
|
import Vector2Control from "../../../../src/view/controller/controls/Vector2Control.js";
|
|
12
|
+
import { CanvasView } from "../../../../src/view/elements/CanvasView.js";
|
|
13
|
+
import EmptyView from "../../../../src/view/elements/EmptyView.js";
|
|
14
14
|
import GroupView from "../../../../src/view/elements/Group.js";
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import { SplatMapOptimizer } from "../../../../src/engine/ecs/terrain/ecs/splat/SplatMapOptimizer.js";
|
|
15
|
+
import View from "../../../../src/view/View.js";
|
|
16
|
+
import DatGuiController from "./DatGuiController.js";
|
|
18
17
|
|
|
19
18
|
class LayersController extends View {
|
|
20
19
|
/**
|
|
@@ -173,12 +172,6 @@ export class TerrainController extends View {
|
|
|
173
172
|
model.__tiles.rebuild();
|
|
174
173
|
}, 'Rebuild');
|
|
175
174
|
|
|
176
|
-
controller.addAction(() => {
|
|
177
|
-
|
|
178
|
-
SplatMapOptimizer.optimizeSynchronous(model.splat)
|
|
179
|
-
|
|
180
|
-
}, 'Optimize Textures');
|
|
181
|
-
|
|
182
175
|
controller.add(model, 'size', { step: 1 });
|
|
183
176
|
controller.add(model, 'resolution').step(1);
|
|
184
177
|
controller.add(model, 'gridScale').step(1).name('Gird Size');
|
package/package.json
CHANGED
|
@@ -159,7 +159,7 @@ export class Uint32Heap {
|
|
|
159
159
|
const size = this.__size;
|
|
160
160
|
|
|
161
161
|
while (true) {
|
|
162
|
-
const l = (
|
|
162
|
+
const l = (i << 1) + 1;
|
|
163
163
|
const r = l + 1;
|
|
164
164
|
|
|
165
165
|
let smallest = i;
|
|
@@ -282,6 +282,15 @@ export class Uint32Heap {
|
|
|
282
282
|
return -1;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
/**
|
|
286
|
+
*
|
|
287
|
+
* @param {number} id
|
|
288
|
+
* @returns {boolean}
|
|
289
|
+
*/
|
|
290
|
+
contains(id){
|
|
291
|
+
return this.find_index_by_id(id) !== -1;
|
|
292
|
+
}
|
|
293
|
+
|
|
285
294
|
/**
|
|
286
295
|
* Clear out all the data, heap will be made empty
|
|
287
296
|
*/
|
package/src/core/graph/Edge.js
CHANGED
|
@@ -86,6 +86,26 @@ export class Edge {
|
|
|
86
86
|
return (this.direction & EdgeDirectionType.Backward) !== 0;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Checks direction of the edge, if the edge is directed towards supplied node - returns true, false otherwise
|
|
91
|
+
* @param {N} node
|
|
92
|
+
* @returns {boolean}
|
|
93
|
+
*/
|
|
94
|
+
isDirectedTowards(node) {
|
|
95
|
+
return (this.first === node && this.direction === EdgeDirectionType.Backward)
|
|
96
|
+
|| (this.second === node && this.direction === EdgeDirectionType.Forward);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Checks direction of the edge, if the edge is directed away from the supplied node - returns true, false otherwise
|
|
101
|
+
* @param {N} node
|
|
102
|
+
* @returns {boolean}
|
|
103
|
+
*/
|
|
104
|
+
isDirectedAwayFrom(node) {
|
|
105
|
+
return (this.first === node && this.direction === EdgeDirectionType.Forward)
|
|
106
|
+
|| (this.second === node && this.direction === EdgeDirectionType.Backward)
|
|
107
|
+
}
|
|
108
|
+
|
|
89
109
|
/**
|
|
90
110
|
* @deprecated
|
|
91
111
|
* @returns {number}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DataType2TypedArrayConstructorMapping } from "../binary/type/DataType2TypedArrayConstructorMapping.js";
|
|
2
1
|
import { assert } from "../assert.js";
|
|
2
|
+
import { DataType2TypedArrayConstructorMapping } from "../binary/type/DataType2TypedArrayConstructorMapping.js";
|
|
3
3
|
import { array_copy } from "../collection/array/array_copy.js";
|
|
4
4
|
|
|
5
5
|
export class SquareMatrix {
|
|
@@ -9,6 +9,8 @@ export class SquareMatrix {
|
|
|
9
9
|
* @param {BinaryDataType|string} type
|
|
10
10
|
*/
|
|
11
11
|
constructor(size, type) {
|
|
12
|
+
assert.isNonNegativeInteger(size, 'size');
|
|
13
|
+
|
|
12
14
|
const TypedArray = DataType2TypedArrayConstructorMapping[type];
|
|
13
15
|
|
|
14
16
|
if (TypedArray === undefined) {
|
|
@@ -162,7 +164,7 @@ export class SquareMatrix {
|
|
|
162
164
|
* @param {number[]} [destination]
|
|
163
165
|
* @param {number} [offset]
|
|
164
166
|
*/
|
|
165
|
-
toArray(destination = new Array(this.length), offset=0) {
|
|
167
|
+
toArray(destination = new Array(this.length), offset = 0) {
|
|
166
168
|
array_copy(this.data, 0, destination, offset, this.length);
|
|
167
169
|
|
|
168
170
|
return destination;
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { Edge } from "./Edge.js";
|
|
2
2
|
|
|
3
3
|
export class WeightedEdge extends Edge {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* @type {number}
|
|
10
|
-
*/
|
|
11
|
-
this.weight = 0;
|
|
12
|
-
}
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @type {number}
|
|
7
|
+
*/
|
|
8
|
+
weight = 0;
|
|
13
9
|
|
|
14
10
|
/**
|
|
15
11
|
*
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { matrix_householder_in_place } from "./matrix_householder_in_place.js";
|
|
2
|
+
import { matrix_qr_in_place } from "./matrix_qr_in_place.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* list of eigen values square matrix (allow non symmetric)
|
|
7
|
+
* NOTE: Modifies input matrix
|
|
8
|
+
* @param {SquareMatrix} mat
|
|
9
|
+
* @return {number[]}
|
|
10
|
+
*/
|
|
11
|
+
export function matrix_eigenvalues_in_place(mat) {
|
|
12
|
+
const n = mat.size;
|
|
13
|
+
matrix_householder_in_place(mat.data, n);
|
|
14
|
+
matrix_qr_in_place(mat.data, n);
|
|
15
|
+
|
|
16
|
+
const result = new Float32Array(n);
|
|
17
|
+
|
|
18
|
+
mat.readDiagonal(result);
|
|
19
|
+
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { SquareMatrix } from "../SquareMatrix.js";
|
|
2
1
|
import { BinaryDataType } from "../../binary/type/BinaryDataType.js";
|
|
3
|
-
import {
|
|
2
|
+
import { SquareMatrix } from "../SquareMatrix.js";
|
|
3
|
+
import { matrix_eigenvalues_in_place } from "./matrix_eigenvalues_in_place.js";
|
|
4
4
|
|
|
5
5
|
function roughly_equal_array_vectors(actual, expected) {
|
|
6
6
|
expect(actual.length).toBe(expected.length);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const EPSILON = 1e-10;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* NxN matrix Householder reduction
|
|
5
|
+
* Return subfunction to upper Hessenberg matrix by Householder transformation
|
|
6
|
+
* @see http://www-in.aut.ac.jp/~minemura/pub/Csimu/C/QRmethod.html
|
|
7
|
+
* @param {number[]} a
|
|
8
|
+
* @param {number} n
|
|
9
|
+
*/
|
|
10
|
+
export function matrix_householder_in_place(a, n) {
|
|
11
|
+
const u = new Float64Array(n);
|
|
12
|
+
const d = new Float64Array(n);
|
|
13
|
+
const ds = new Float64Array(n);
|
|
14
|
+
|
|
15
|
+
let i, j, k;
|
|
16
|
+
let sum;
|
|
17
|
+
|
|
18
|
+
for (k = 0; k <= n - 3; k++) {
|
|
19
|
+
|
|
20
|
+
for (i = 0; i <= k; i++) {
|
|
21
|
+
u[i] = 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (i = k + 1; i < n; i++) {
|
|
25
|
+
u[i] = a[n * i + k];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Build transformation matrix H
|
|
29
|
+
sum = 0.0;
|
|
30
|
+
|
|
31
|
+
for (i = k + 1; i < n; i++) {
|
|
32
|
+
sum = sum + u[i] * u[i];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const u_k_1 = u[k + 1];
|
|
36
|
+
|
|
37
|
+
const u_k_1_abs = Math.abs(u_k_1);
|
|
38
|
+
if (u_k_1_abs < EPSILON) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const sigma = Math.sqrt(sum) * u_k_1 / u_k_1_abs;
|
|
43
|
+
|
|
44
|
+
u[k + 1] += sigma;
|
|
45
|
+
|
|
46
|
+
const v_norm = Math.sqrt(2.0 * sigma * u[k + 1]);
|
|
47
|
+
|
|
48
|
+
for (i = k + 1; i < n; i++) {
|
|
49
|
+
u[i] /= v_norm;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Similarity transformation
|
|
53
|
+
for (i = 0; i < n; i++) {
|
|
54
|
+
d[i] = 0.0;
|
|
55
|
+
ds[i] = 0.0;
|
|
56
|
+
for (j = k + 1; j <= n - 1; j++) {
|
|
57
|
+
const u_j = u[j];
|
|
58
|
+
|
|
59
|
+
d[i] += a[n * i + j] * u_j;
|
|
60
|
+
ds[i] += a[n * j + i] * u_j;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let ud = 0.0;
|
|
65
|
+
let uds = 0.0;
|
|
66
|
+
|
|
67
|
+
for (i = k + 1; i < n; i++) {
|
|
68
|
+
const u_i = u[i];
|
|
69
|
+
|
|
70
|
+
ud += u_i * d[i];
|
|
71
|
+
uds += u_i * ds[i];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (i = 0; i < n; i++) {
|
|
75
|
+
const u_i = u[i];
|
|
76
|
+
|
|
77
|
+
d[i] = 2.0 * (d[i] - ud * u_i);
|
|
78
|
+
ds[i] = 2.0 * (ds[i] - uds * u_i);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
for (i = 0; i < n; i++) {
|
|
82
|
+
const u_i = u[i];
|
|
83
|
+
const d_i = d[i];
|
|
84
|
+
|
|
85
|
+
const n_i = n * i;
|
|
86
|
+
|
|
87
|
+
for (j = 0; j < n; j++) {
|
|
88
|
+
a[n_i + j] -= u_i * ds[j] + d_i * u[j];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -1,97 +1,5 @@
|
|
|
1
1
|
const EPSILON = 1e-10;
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* NxN matrix Householder reduction
|
|
5
|
-
* Return subfunction to upper Hessenberg matrix by Householder transformation
|
|
6
|
-
* @see http://www-in.aut.ac.jp/~minemura/pub/Csimu/C/QRmethod.html
|
|
7
|
-
* @param {number[]} a
|
|
8
|
-
* @param {number} n
|
|
9
|
-
*/
|
|
10
|
-
function householder_in_place(a, n) {
|
|
11
|
-
const u = new Float64Array(n);
|
|
12
|
-
const d = new Float64Array(n);
|
|
13
|
-
const ds = new Float64Array(n);
|
|
14
|
-
|
|
15
|
-
let i, j, k;
|
|
16
|
-
let sum;
|
|
17
|
-
|
|
18
|
-
for (k = 0; k <= n - 3; k++) {
|
|
19
|
-
|
|
20
|
-
for (i = 0; i <= k; i++) {
|
|
21
|
-
u[i] = 0;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
for (i = k + 1; i < n; i++) {
|
|
25
|
-
u[i] = a[n * i + k];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Build transformation matrix H
|
|
29
|
-
sum = 0.0;
|
|
30
|
-
|
|
31
|
-
for (i = k + 1; i < n; i++) {
|
|
32
|
-
sum = sum + u[i] * u[i];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const u_k_1 = u[k + 1];
|
|
36
|
-
|
|
37
|
-
const u_k_1_abs = Math.abs(u_k_1);
|
|
38
|
-
if (u_k_1_abs < EPSILON) {
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const sigma = Math.sqrt(sum) * u_k_1 / u_k_1_abs;
|
|
43
|
-
|
|
44
|
-
u[k + 1] += sigma;
|
|
45
|
-
|
|
46
|
-
const v_norm = Math.sqrt(2.0 * sigma * u[k + 1]);
|
|
47
|
-
|
|
48
|
-
for (i = k + 1; i < n; i++) {
|
|
49
|
-
u[i] /= v_norm;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Similarity transformation
|
|
53
|
-
for (i = 0; i < n; i++) {
|
|
54
|
-
d[i] = 0.0;
|
|
55
|
-
ds[i] = 0.0;
|
|
56
|
-
for (j = k + 1; j <= n - 1; j++) {
|
|
57
|
-
const u_j = u[j];
|
|
58
|
-
|
|
59
|
-
d[i] += a[n * i + j] * u_j;
|
|
60
|
-
ds[i] += a[n * j + i] * u_j;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
let ud = 0.0;
|
|
65
|
-
let uds = 0.0;
|
|
66
|
-
|
|
67
|
-
for (i = k + 1; i < n; i++) {
|
|
68
|
-
const u_i = u[i];
|
|
69
|
-
|
|
70
|
-
ud += u_i * d[i];
|
|
71
|
-
uds += u_i * ds[i];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
for (i = 0; i < n; i++) {
|
|
75
|
-
const u_i = u[i];
|
|
76
|
-
|
|
77
|
-
d[i] = 2.0 * (d[i] - ud * u_i);
|
|
78
|
-
ds[i] = 2.0 * (ds[i] - uds * u_i);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
for (i = 0; i < n; i++) {
|
|
82
|
-
const u_i = u[i];
|
|
83
|
-
const d_i = d[i];
|
|
84
|
-
|
|
85
|
-
const n_i = n * i;
|
|
86
|
-
|
|
87
|
-
for (j = 0; j < n; j++) {
|
|
88
|
-
a[n_i + j] -= u_i * ds[j] + d_i * u[j];
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
3
|
/**
|
|
96
4
|
* Perform QR factorization in-place
|
|
97
5
|
* Subfunction that analyzes eigenvalues by QR decomposition
|
|
@@ -99,7 +7,7 @@ function householder_in_place(a, n) {
|
|
|
99
7
|
* @param {number[]} a Square matrix
|
|
100
8
|
* @param {number} n size of the matrix in single dimension
|
|
101
9
|
*/
|
|
102
|
-
function
|
|
10
|
+
export function matrix_qr_in_place(a, n) {
|
|
103
11
|
const q = new Float64Array(n * n);
|
|
104
12
|
const w = new Float64Array(n);
|
|
105
13
|
|
|
@@ -207,23 +115,4 @@ function qr_in_place(a, n) {
|
|
|
207
115
|
a[n * i + i] += mu;
|
|
208
116
|
}
|
|
209
117
|
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* list of eigen values square matrix (allow non symmetric)
|
|
215
|
-
* NOTE: Modifies input matrix
|
|
216
|
-
* @param {SquareMatrix} mat
|
|
217
|
-
* @return {number[]}
|
|
218
|
-
*/
|
|
219
|
-
export function matrix_eigenvalues_in_place(mat) {
|
|
220
|
-
const n = mat.size;
|
|
221
|
-
householder_in_place(mat.data, n);
|
|
222
|
-
qr_in_place(mat.data, n);
|
|
223
|
-
|
|
224
|
-
const result = new Float32Array(n);
|
|
225
|
-
|
|
226
|
-
mat.readDiagonal(result);
|
|
227
|
-
|
|
228
|
-
return result;
|
|
229
|
-
}
|
|
118
|
+
}
|
|
@@ -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
|
/**
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import { assert } from "../../assert.js";
|
|
2
2
|
import Signal from "../../events/signal/Signal.js";
|
|
3
|
-
import { NodeContainer } from "./NodeContainer.js";
|
|
4
3
|
import { Edge, EdgeDirectionType } from "../Edge.js";
|
|
4
|
+
import { NodeContainer } from "./NodeContainer.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
+
* Reconstruct path from search metadata
|
|
7
8
|
* @template T
|
|
8
9
|
* @param {NodeContainer<T>} goal_node_container
|
|
9
|
-
* @param {Map<NodeContainer<T>,NodeContainer<T>>}
|
|
10
|
-
* @returns {T[]}
|
|
10
|
+
* @param {Map<NodeContainer<T>,NodeContainer<T>>} came_from
|
|
11
|
+
* @returns {T[]} Nodes comprising the path from start to goal
|
|
11
12
|
*/
|
|
12
|
-
function construct_path(goal_node_container,
|
|
13
|
+
function construct_path(goal_node_container, came_from) {
|
|
13
14
|
const result = [];
|
|
15
|
+
|
|
14
16
|
let c = goal_node_container;
|
|
17
|
+
|
|
15
18
|
do {
|
|
16
19
|
result.unshift(c.node);
|
|
17
|
-
c =
|
|
20
|
+
c = came_from.get(c);
|
|
18
21
|
} while (c !== undefined);
|
|
19
22
|
|
|
20
23
|
return result;
|
|
@@ -28,16 +31,21 @@ export class Graph {
|
|
|
28
31
|
/**
|
|
29
32
|
*
|
|
30
33
|
* @type {Map<N, NodeContainer<N>>}
|
|
34
|
+
* @readonly
|
|
31
35
|
* @private
|
|
32
36
|
*/
|
|
33
37
|
__nodes = new Map();
|
|
34
38
|
/**
|
|
35
39
|
*
|
|
36
40
|
* @type {Set<Edge<N>>}
|
|
41
|
+
* @readonly
|
|
37
42
|
* @private
|
|
38
43
|
*/
|
|
39
44
|
__edges = new Set();
|
|
40
45
|
|
|
46
|
+
/**
|
|
47
|
+
* @readonly
|
|
48
|
+
*/
|
|
41
49
|
on = {
|
|
42
50
|
/**
|
|
43
51
|
* @type {Signal<N,this>}
|
|
@@ -171,6 +179,14 @@ export class Graph {
|
|
|
171
179
|
return container.getEdgeCount();
|
|
172
180
|
}
|
|
173
181
|
|
|
182
|
+
/**
|
|
183
|
+
*
|
|
184
|
+
* @returns {N[]}
|
|
185
|
+
*/
|
|
186
|
+
get nodes() {
|
|
187
|
+
return Array.from(this.getNodes());
|
|
188
|
+
}
|
|
189
|
+
|
|
174
190
|
/**
|
|
175
191
|
* Do not modify this set directly
|
|
176
192
|
* @return {Iterable<N>}
|
|
@@ -191,10 +207,10 @@ export class Graph {
|
|
|
191
207
|
*
|
|
192
208
|
* @param {N} source
|
|
193
209
|
* @param {N} target
|
|
194
|
-
* @param {EdgeDirectionType} type
|
|
210
|
+
* @param {EdgeDirectionType} [type] Undirected by default
|
|
195
211
|
* @returns {Edge<N>}
|
|
196
212
|
*/
|
|
197
|
-
createEdge(source, target, type) {
|
|
213
|
+
createEdge(source, target, type = EdgeDirectionType.Undirected) {
|
|
198
214
|
const edge = new Edge(source, target);
|
|
199
215
|
|
|
200
216
|
edge.direction = type;
|
|
@@ -376,13 +392,27 @@ export class Graph {
|
|
|
376
392
|
const edge_count = edges.length;
|
|
377
393
|
|
|
378
394
|
for (let i = 0; i < edge_count; i++) {
|
|
379
|
-
|
|
380
|
-
result[i] = edge;
|
|
395
|
+
result[i] = edges[i];
|
|
381
396
|
}
|
|
382
397
|
|
|
383
398
|
return edge_count;
|
|
384
399
|
}
|
|
385
400
|
|
|
401
|
+
/**
|
|
402
|
+
*
|
|
403
|
+
* @param {N} node
|
|
404
|
+
* @returns {N[]}
|
|
405
|
+
*/
|
|
406
|
+
getNeighbours(node) {
|
|
407
|
+
const container = this.__nodes.get(node);
|
|
408
|
+
|
|
409
|
+
if (container === undefined) {
|
|
410
|
+
return [];
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return container.neighbours;
|
|
414
|
+
}
|
|
415
|
+
|
|
386
416
|
/**
|
|
387
417
|
*
|
|
388
418
|
* @param {N} node
|