@flighthq/spatial 0.3.0-next.1392.f0bd0cc → 0.3.0-next.1422.b585c0c
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/dist/explainSpatialIndexing.d.ts.map +1 -1
- package/dist/explainSpatialIndexing.js +3 -2
- package/dist/explainSpatialIndexing.js.map +1 -1
- package/dist/formatSpatialIndexingNotice.d.ts.map +1 -1
- package/dist/formatSpatialIndexingNotice.js +15 -3
- package/dist/formatSpatialIndexingNotice.js.map +1 -1
- package/dist/spatialIndex.js +3 -3
- package/dist/spatialIndex.js.map +1 -1
- package/dist/uniformGrid.d.ts.map +1 -1
- package/dist/uniformGrid.js +64 -36
- package/dist/uniformGrid.js.map +1 -1
- package/package.json +3 -3
- package/src/formatSpatialIndexingNotice.test.ts +63 -5
- package/src/uniformGrid.test.ts +284 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explainSpatialIndexing.d.ts","sourceRoot":"","sources":["../src/explainSpatialIndexing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"explainSpatialIndexing.d.ts","sourceRoot":"","sources":["../src/explainSpatialIndexing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAY1G,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,eAAe,GAAG,0BAA0B,CAErH"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// Reports how the index is currently holding `id`, as plain data. Pure: reads only, indexes nothing,
|
|
2
2
|
// never throws on an unknown id, and retains no reference to the backend. Import it to answer "why is
|
|
3
3
|
// this object not in my query results?" — `absent` means it was never inserted or was removed,
|
|
4
|
-
// `declined` means its bounds were non-finite and it is deliberately not held, `overflow`
|
|
5
|
-
// held but
|
|
4
|
+
// `declined` means its bounds were non-finite or inverted and it is deliberately not held, `overflow`
|
|
5
|
+
// means it is held but cannot be usefully bucketed, and `cells` reports the bucket count the
|
|
6
|
+
// per-object bound caps.
|
|
6
7
|
//
|
|
7
8
|
// This is the pull half of the diagnostics convention, and the measurement seam a regression test
|
|
8
9
|
// asserts the cost bound against: `bucketCount` is the number that goes unbounded when the bound is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explainSpatialIndexing.js","sourceRoot":"","sources":["../src/explainSpatialIndexing.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,sGAAsG;AACtG,+FAA+F;AAC/F,sGAAsG;AACtG,
|
|
1
|
+
{"version":3,"file":"explainSpatialIndexing.js","sourceRoot":"","sources":["../src/explainSpatialIndexing.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,sGAAsG;AACtG,+FAA+F;AAC/F,sGAAsG;AACtG,6FAA6F;AAC7F,yBAAyB;AACzB,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AACpG,yDAAyD;AACzD,MAAM,UAAU,sBAAsB,CAAC,KAA6B,EAAE,EAAmB;IACvF,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatSpatialIndexingNotice.d.ts","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AActE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"formatSpatialIndexingNotice.d.ts","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AActE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,MAAM,CAsB3F"}
|
|
@@ -10,14 +10,26 @@ import { MAX_INDEXED_CELLS_PER_OBJECT } from './uniformGrid';
|
|
|
10
10
|
//
|
|
11
11
|
// setSpatialIndexingGuard((notice) => logWarn({ message: formatSpatialIndexingNotice(notice) }, 'spatial'));
|
|
12
12
|
export function formatSpatialIndexingNotice(notice) {
|
|
13
|
+
if (notice.reason === 'invalid-cell-size') {
|
|
14
|
+
return `createUniformGridSpatialBackend(${notice.cellSize}): cellSize must be a positive finite number. ${notice.operation}SpatialObject(${notice.id}) used the bounded overflow path instead, so results remain correct but queries scan this object.`;
|
|
15
|
+
}
|
|
16
|
+
if (notice.reason === 'inverted-bounds') {
|
|
17
|
+
return `${notice.operation}SpatialObject(${notice.id}): minX/minY must not exceed maxX/maxY, so the object was not indexed and no query will return it. The operation returns false for this — normalize or correct the bounds upstream.`;
|
|
18
|
+
}
|
|
19
|
+
if (notice.reason === 'missing-id') {
|
|
20
|
+
if (notice.operation === 'remove') {
|
|
21
|
+
return `removeSpatialObject(${notice.id}): the id was not indexed, so removal was a no-op. Check the object's indexing lifecycle if this was unexpected.`;
|
|
22
|
+
}
|
|
23
|
+
return `updateSpatialObject(${notice.id}): the id was not indexed, so update used its documented insert behavior and left the object in '${notice.mode}' mode. Use insertSpatialObject for a new id, or check the object's indexing lifecycle.`;
|
|
24
|
+
}
|
|
13
25
|
if (notice.mode === 'declined') {
|
|
14
|
-
return
|
|
26
|
+
return `${notice.operation}SpatialObject(${notice.id}): the bounds are not finite, so the object was not indexed and no query will return it. The operation returns false for this — check the sentinel, and check what produced NaN/Infinity bounds upstream.`;
|
|
15
27
|
}
|
|
16
28
|
if (notice.mode === 'overflow') {
|
|
17
|
-
return
|
|
29
|
+
return `${notice.operation}SpatialObject(${notice.id}): the bounds span ${notice.wouldOccupyBucketCount} cells, over the ${MAX_INDEXED_CELLS_PER_OBJECT} per-object budget, so the object is held in the flat overflow list instead of the grid. Results are unaffected. If this is not a one-off outlier, the grid's cellSize is too small for the objects being indexed — size it to a typical object.`;
|
|
18
30
|
}
|
|
19
31
|
// `cells` and `absent` are ordinary outcomes no guard reports, so reaching here means a backend
|
|
20
32
|
// notified about something this text does not cover. Say exactly that rather than inventing advice.
|
|
21
|
-
return
|
|
33
|
+
return `${notice.operation}SpatialObject(${notice.id}): indexed as '${notice.mode}', which carries no caller-facing advice.`;
|
|
22
34
|
}
|
|
23
35
|
//# sourceMappingURL=formatSpatialIndexingNotice.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatSpatialIndexingNotice.js","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D,qGAAqG;AACrG,sGAAsG;AACtG,2FAA2F;AAC3F,EAAE;AACF,4FAA4F;AAC5F,qGAAqG;AACrG,sGAAsG;AACtG,gGAAgG;AAChG,EAAE;AACF,+GAA+G;AAC/G,MAAM,UAAU,2BAA2B,CAAC,MAAuC;IACjF,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,
|
|
1
|
+
{"version":3,"file":"formatSpatialIndexingNotice.js","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D,qGAAqG;AACrG,sGAAsG;AACtG,2FAA2F;AAC3F,EAAE;AACF,4FAA4F;AAC5F,qGAAqG;AACrG,sGAAsG;AACtG,gGAAgG;AAChG,EAAE;AACF,+GAA+G;AAC/G,MAAM,UAAU,2BAA2B,CAAC,MAAuC;IACjF,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;QAC1C,OAAO,mCAAmC,MAAM,CAAC,QAAQ,iDAAiD,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,mGAAmG,CAAC;IAC1P,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACxC,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,qLAAqL,CAAC;IAC5O,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,uBAAuB,MAAM,CAAC,EAAE,kHAAkH,CAAC;QAC5J,CAAC;QACD,OAAO,uBAAuB,MAAM,CAAC,EAAE,oGAAoG,MAAM,CAAC,IAAI,yFAAyF,CAAC;IAClP,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,2MAA2M,CAAC;IAClQ,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,sBAAsB,MAAM,CAAC,sBAAsB,oBAAoB,4BAA4B,kPAAkP,CAAC;IAC5Y,CAAC;IACD,gGAAgG;IAChG,oGAAoG;IACpG,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,kBAAkB,MAAM,CAAC,IAAI,2CAA2C,CAAC;AAC/H,CAAC"}
|
package/dist/spatialIndex.js
CHANGED
|
@@ -16,9 +16,9 @@ export function createSpatialIndex(backend) {
|
|
|
16
16
|
}
|
|
17
17
|
// Adds an object to the index under `id` with its current bounds. The bounds are copied; the caller
|
|
18
18
|
// may reuse its own value afterward. Returns false when the bounds cannot be indexed at all
|
|
19
|
-
// (non-finite) — the object is then absent from every query rather than present at a
|
|
20
|
-
// position. Oversized-but-
|
|
21
|
-
// to hold them. explainSpatialIndexing reports which happened.
|
|
19
|
+
// (non-finite or inverted) — the object is then absent from every query rather than present at a
|
|
20
|
+
// nonsense position. Oversized-but-valid bounds return true and stay fully queryable; the backend
|
|
21
|
+
// decides how to hold them. explainSpatialIndexing reports which happened.
|
|
22
22
|
export function insertSpatialObject(index, id, bounds) {
|
|
23
23
|
return index.runtime.backend.insertSpatialObject(id, bounds);
|
|
24
24
|
}
|
package/dist/spatialIndex.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spatialIndex.js","sourceRoot":"","sources":["../src/spatialIndex.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAEhE,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;AAC5C,CAAC;AAED,yFAAyF;AACzF,kGAAkG;AAClG,mGAAmG;AACnG,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAAC,OAA6B;IAC9D,OAAO;QACL,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,IAAI,+BAA+B,CAAC,yBAAyB,CAAC;SAC/E;KACF,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,4FAA4F;AAC5F,
|
|
1
|
+
{"version":3,"file":"spatialIndex.js","sourceRoot":"","sources":["../src/spatialIndex.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAEhE,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;AAC5C,CAAC;AAED,yFAAyF;AACzF,kGAAkG;AAClG,mGAAmG;AACnG,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAAC,OAA6B;IAC9D,OAAO;QACL,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,IAAI,+BAA+B,CAAC,yBAAyB,CAAC;SAC/E;KACF,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,4FAA4F;AAC5F,iGAAiG;AACjG,kGAAkG;AAClG,2EAA2E;AAC3E,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,EAAmB,EACnB,MAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,mGAAmG;AACnG,iGAAiG;AACjG,8FAA8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,GAAkB;IACjF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,CAAS,EAAE,CAAS,EAAE,GAAsB;IAC3G,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,iGAAiG;AACjG,kGAAkG;AAClG,MAAM,UAAU,eAAe,CAC7B,KAA6B,EAC7B,CAAS,EACT,CAAS,EACT,EAAU,EACV,EAAU,EACV,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAChC,KAA6B,EAC7B,MAA6B,EAC7B,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,mBAAmB,CAAC,KAA6B,EAAE,EAAmB;IACpF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,oGAAoG;AACpG,qGAAqG;AACrG,sGAAsG;AACtG,oBAAoB;AACpB,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,EAAmB,EACnB,MAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,qGAAqG;AACrG,MAAM,yBAAyB,GAAG,GAAG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uniformGrid.d.ts","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,mBAAmB,
|
|
1
|
+
{"version":3,"file":"uniformGrid.d.ts","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,mBAAmB,EAGnB,oBAAoB,EAMrB,MAAM,0BAA0B,CAAC;AAiBlC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAejD,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAkDrF;AAKD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAEhF"}
|
package/dist/uniformGrid.js
CHANGED
|
@@ -13,41 +13,47 @@ import { containsRectanglePointXY, intersectsRectangle } from '@flighthq/geometr
|
|
|
13
13
|
// everything, so the cell index tells the queries almost nothing and a linear scan answers the same
|
|
14
14
|
// question at a bounded cost. 1024 cells is a 32×32 block — an object 32× the cell size on each axis,
|
|
15
15
|
// far past the "cell size ≈ typical object size" the grid is built around. An object over the budget
|
|
16
|
-
// is a signal the cell size is wrong for the workload, which
|
|
16
|
+
// is a signal the cell size is wrong for the workload, which the indexing guard reports.
|
|
17
17
|
export const MAX_INDEXED_CELLS_PER_OBJECT = 1024;
|
|
18
18
|
// Builds a uniform-grid (spatial-hash) backend: an object's AABB is mapped to the rectangular block
|
|
19
19
|
// of fixed-size cells it covers, and each cell holds the ids overlapping it. Co-located objects share
|
|
20
20
|
// a cell, so candidate pairs and region/point/ray hits are found by looking only at the relevant
|
|
21
21
|
// cells instead of scanning every object. `cellSize` is the world-space side length of one cell; a
|
|
22
|
-
// good value is roughly the size of a typical object (too small over-spans
|
|
23
|
-
// cells, too large lumps unrelated objects together).
|
|
24
|
-
//
|
|
22
|
+
// good value is a positive finite number roughly the size of a typical object (too small over-spans
|
|
23
|
+
// large objects across many cells, too large lumps unrelated objects together). An invalid size uses
|
|
24
|
+
// the bounded overflow path to keep results correct and reports through the indexing guard. No
|
|
25
|
+
// import-time side effect — the caller constructs a grid explicitly, and createSpatialIndex uses
|
|
26
|
+
// this as its default index.
|
|
25
27
|
//
|
|
26
28
|
// Object size does not set the cost: an AABB spanning more than MAX_INDEXED_CELLS_PER_OBJECT cells
|
|
27
|
-
// goes to a flat overflow list that every query scans, and non-finite bounds are declined
|
|
28
|
-
// with a false sentinel. Both are visible through explainSpatialIndexing.
|
|
29
|
+
// goes to a flat overflow list that every query scans, and non-finite or inverted bounds are declined
|
|
30
|
+
// outright with a false sentinel. Both are visible through explainSpatialIndexing.
|
|
29
31
|
export function createUniformGridSpatialBackend(cellSize) {
|
|
30
32
|
const grid = {
|
|
31
33
|
cellSize,
|
|
32
34
|
cells: new Map(),
|
|
33
35
|
bounds: new Map(),
|
|
34
36
|
overflow: new Set(),
|
|
35
|
-
declined: new
|
|
37
|
+
declined: new Map(),
|
|
36
38
|
minCellX: 0,
|
|
37
39
|
minCellY: 0,
|
|
38
40
|
maxCellX: 0,
|
|
39
41
|
maxCellY: 0,
|
|
40
42
|
seen: new Set(),
|
|
43
|
+
pairIds: [],
|
|
41
44
|
};
|
|
42
45
|
return {
|
|
43
46
|
insertSpatialObject(id, bounds) {
|
|
44
|
-
return _insertIntoGrid(grid, id, bounds);
|
|
47
|
+
return _insertIntoGrid(grid, id, bounds, 'insert');
|
|
45
48
|
},
|
|
46
49
|
updateSpatialObject(id, bounds) {
|
|
47
50
|
return _updateGridObject(grid, id, bounds);
|
|
48
51
|
},
|
|
49
52
|
removeSpatialObject(id) {
|
|
53
|
+
const wasMissing = !grid.bounds.has(id) && !grid.declined.has(id);
|
|
50
54
|
_removeFromGrid(grid, id);
|
|
55
|
+
if (wasMissing)
|
|
56
|
+
_reportGridIndexing(grid, id, 'absent', 'remove', 'missing-id', 0);
|
|
51
57
|
},
|
|
52
58
|
clearSpatialIndex() {
|
|
53
59
|
grid.cells.clear();
|
|
@@ -55,6 +61,7 @@ export function createUniformGridSpatialBackend(cellSize) {
|
|
|
55
61
|
grid.overflow.clear();
|
|
56
62
|
grid.declined.clear();
|
|
57
63
|
grid.seen.clear();
|
|
64
|
+
grid.pairIds.length = 0;
|
|
58
65
|
},
|
|
59
66
|
explainSpatialIndexing(id) {
|
|
60
67
|
return _explainGridIndexing(grid, id);
|
|
@@ -73,11 +80,9 @@ export function createUniformGridSpatialBackend(cellSize) {
|
|
|
73
80
|
},
|
|
74
81
|
};
|
|
75
82
|
}
|
|
76
|
-
// Installs the indexing guard consulted
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
// than per-grid: it is a development diagnostic, and an application debugging a missing object wants
|
|
80
|
-
// it on for every index at once.
|
|
83
|
+
// Installs the indexing guard consulted for invalid configuration or bounds, missing-id operations,
|
|
84
|
+
// and overflow routing; null uninstalls it. Module-scoped rather than per-grid: it is a development
|
|
85
|
+
// diagnostic, and an application debugging an index wants it on for every grid at once.
|
|
81
86
|
export function setSpatialIndexingGuard(guard) {
|
|
82
87
|
_indexingGuard = guard;
|
|
83
88
|
}
|
|
@@ -93,8 +98,7 @@ function _cellKey(cx, cy) {
|
|
|
93
98
|
}
|
|
94
99
|
// Fills a scratch RectangleLike (x/y/width/height) from a SpatialAabb (min/max corners) so the
|
|
95
100
|
// geometry rectangle-overlap and point-containment helpers can be reused instead of re-deriving the
|
|
96
|
-
// AABB math here.
|
|
97
|
-
// which the geometry helpers still normalize internally.
|
|
101
|
+
// AABB math here. Stored AABBs are normalized because insert declines inverted bounds.
|
|
98
102
|
function _fillRectFromAabb(out, aabb) {
|
|
99
103
|
out.x = aabb.minX;
|
|
100
104
|
out.y = aabb.minY;
|
|
@@ -103,8 +107,9 @@ function _fillRectFromAabb(out, aabb) {
|
|
|
103
107
|
}
|
|
104
108
|
// Reports how `id` is currently held. Pure: reads only, allocates only the returned record.
|
|
105
109
|
function _explainGridIndexing(grid, id) {
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
const declineReason = grid.declined.get(id);
|
|
111
|
+
if (declineReason !== undefined)
|
|
112
|
+
return { bucketCount: 0, id, mode: 'declined', reason: declineReason };
|
|
108
113
|
if (grid.overflow.has(id))
|
|
109
114
|
return { bucketCount: 0, id, mode: 'overflow', reason: null };
|
|
110
115
|
const bounds = grid.bounds.get(id);
|
|
@@ -115,38 +120,47 @@ function _explainGridIndexing(grid, id) {
|
|
|
115
120
|
// Adds an object to the index, storing a private copy of the bounds; the caller may safely mutate or
|
|
116
121
|
// reuse the passed bounds afterward. Returns false only for bounds that cannot be indexed at all.
|
|
117
122
|
//
|
|
118
|
-
//
|
|
123
|
+
// Five outcomes, and which one applies is decided *before* any cell is touched — that ordering is
|
|
119
124
|
// the whole point, since deciding afterward would mean walking the cells to find out they were too
|
|
120
125
|
// many:
|
|
121
126
|
// - non-finite bounds are declined. There is no cell range to compute, and storing them would let a
|
|
122
127
|
// NaN leak into every later overlap test, so the object is left out of the index entirely and the
|
|
123
128
|
// caller gets a false sentinel rather than an exception or a silent no-op.
|
|
129
|
+
// - inverted bounds are likewise declined because min/max corners do not describe an AABB.
|
|
130
|
+
// - a non-positive or non-finite cell size routes valid objects to overflow, preserving query
|
|
131
|
+
// correctness through the bounded flat scan while the indexing guard reports the configuration.
|
|
124
132
|
// - bounds spanning more than MAX_INDEXED_CELLS_PER_OBJECT cells go to the overflow list, which
|
|
125
133
|
// every query scans. Bounded by the object count instead of the object's size.
|
|
126
134
|
// - everything else takes the ordinary path: one entry in each cell it covers.
|
|
127
|
-
function _insertIntoGrid(grid, id, bounds) {
|
|
135
|
+
function _insertIntoGrid(grid, id, bounds, operation) {
|
|
128
136
|
if (!Number.isFinite(bounds.minX) ||
|
|
129
137
|
!Number.isFinite(bounds.minY) ||
|
|
130
138
|
!Number.isFinite(bounds.maxX) ||
|
|
131
139
|
!Number.isFinite(bounds.maxY)) {
|
|
132
|
-
grid.declined.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
grid.declined.set(id, 'non-finite-bounds');
|
|
141
|
+
_reportGridIndexing(grid, id, 'declined', operation, 'non-finite-bounds', 0);
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if (bounds.maxX < bounds.minX || bounds.maxY < bounds.minY) {
|
|
145
|
+
grid.declined.set(id, 'inverted-bounds');
|
|
146
|
+
_reportGridIndexing(grid, id, 'declined', operation, 'inverted-bounds', 0);
|
|
136
147
|
return false;
|
|
137
148
|
}
|
|
138
149
|
const cs = grid.cellSize;
|
|
139
150
|
const copy = { minX: bounds.minX, minY: bounds.minY, maxX: bounds.maxX, maxY: bounds.maxY };
|
|
151
|
+
if (!(cs > 0 && Number.isFinite(cs))) {
|
|
152
|
+
grid.bounds.set(id, copy);
|
|
153
|
+
grid.overflow.add(id);
|
|
154
|
+
_reportGridIndexing(grid, id, 'overflow', operation, 'invalid-cell-size', 0);
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
140
157
|
const spanned = _spannedCellCount(cs, copy);
|
|
141
|
-
// Written as a negated `<=` so
|
|
142
|
-
//
|
|
143
|
-
// never runs, silently indexing nothing.
|
|
158
|
+
// Written as a negated `<=` so an unrepresentable span falls to overflow rather than through to a
|
|
159
|
+
// loop that cannot index it.
|
|
144
160
|
if (!(spanned <= MAX_INDEXED_CELLS_PER_OBJECT)) {
|
|
145
161
|
grid.bounds.set(id, copy);
|
|
146
162
|
grid.overflow.add(id);
|
|
147
|
-
|
|
148
|
-
_indexingGuard({ id, mode: 'overflow', reason: null, wouldOccupyBucketCount: spanned });
|
|
149
|
-
}
|
|
163
|
+
_reportGridIndexing(grid, id, 'overflow', operation, null, spanned);
|
|
150
164
|
return true;
|
|
151
165
|
}
|
|
152
166
|
const cx0 = _cellIndex(copy.minX, cs);
|
|
@@ -191,13 +205,16 @@ function _insertIntoGrid(grid, id, bounds) {
|
|
|
191
205
|
// usually stays inside this range, so its dominant cost becomes four field writes instead of a
|
|
192
206
|
// remove-and-reinsert walk. Every mode or range transition keeps using the shared slow path below.
|
|
193
207
|
function _updateGridObject(grid, id, bounds) {
|
|
208
|
+
const wasMissing = !grid.bounds.has(id) && !grid.declined.has(id);
|
|
194
209
|
const previous = grid.bounds.get(id);
|
|
195
210
|
if (previous !== undefined &&
|
|
196
211
|
!grid.overflow.has(id) &&
|
|
197
212
|
Number.isFinite(bounds.minX) &&
|
|
198
213
|
Number.isFinite(bounds.minY) &&
|
|
199
214
|
Number.isFinite(bounds.maxX) &&
|
|
200
|
-
Number.isFinite(bounds.maxY)
|
|
215
|
+
Number.isFinite(bounds.maxY) &&
|
|
216
|
+
bounds.minX <= bounds.maxX &&
|
|
217
|
+
bounds.minY <= bounds.maxY) {
|
|
201
218
|
const cs = grid.cellSize;
|
|
202
219
|
const spanned = _spannedCellCount(cs, bounds);
|
|
203
220
|
if (spanned <= MAX_INDEXED_CELLS_PER_OBJECT &&
|
|
@@ -213,7 +230,12 @@ function _updateGridObject(grid, id, bounds) {
|
|
|
213
230
|
}
|
|
214
231
|
}
|
|
215
232
|
_removeFromGrid(grid, id);
|
|
216
|
-
|
|
233
|
+
const inserted = _insertIntoGrid(grid, id, bounds, 'update');
|
|
234
|
+
if (wasMissing) {
|
|
235
|
+
const explanation = _explainGridIndexing(grid, id);
|
|
236
|
+
_reportGridIndexing(grid, id, explanation.mode, 'update', 'missing-id', 0);
|
|
237
|
+
}
|
|
238
|
+
return inserted;
|
|
217
239
|
}
|
|
218
240
|
// Reports whether an AABB contains the point (`x`,`y`), reusing the geometry rectangle helper.
|
|
219
241
|
function _isSpatialAabbContainsPoint(aabb, x, y) {
|
|
@@ -335,11 +357,14 @@ function _queryGridOverflowPairs(grid, out) {
|
|
|
335
357
|
function _queryGridPairs(grid, out) {
|
|
336
358
|
out.length = 0;
|
|
337
359
|
const cs = grid.cellSize;
|
|
360
|
+
const list = grid.pairIds;
|
|
338
361
|
for (const cell of grid.cells.values()) {
|
|
339
362
|
const ids = cell.ids;
|
|
340
363
|
if (ids.size < 2)
|
|
341
364
|
continue;
|
|
342
|
-
|
|
365
|
+
list.length = 0;
|
|
366
|
+
for (const id of ids)
|
|
367
|
+
list.push(id);
|
|
343
368
|
for (let i = 0; i < list.length; i++) {
|
|
344
369
|
for (let j = i + 1; j < list.length; j++) {
|
|
345
370
|
let a = list[i];
|
|
@@ -363,6 +388,11 @@ function _queryGridPairs(grid, out) {
|
|
|
363
388
|
if (grid.overflow.size !== 0)
|
|
364
389
|
_queryGridOverflowPairs(grid, out);
|
|
365
390
|
}
|
|
391
|
+
function _reportGridIndexing(grid, id, mode, operation, reason, wouldOccupyBucketCount) {
|
|
392
|
+
if (_indexingGuard === null)
|
|
393
|
+
return;
|
|
394
|
+
_indexingGuard({ cellSize: grid.cellSize, id, mode, operation, reason, wouldOccupyBucketCount });
|
|
395
|
+
}
|
|
366
396
|
// Gathers the ids in the cell containing the point, then confirms each against its real bounds. A
|
|
367
397
|
// single cell holds each id at most once, so no dedup pass is needed. Overflowed objects hold no cell
|
|
368
398
|
// and are tested directly; they cannot collide with the cell gather, so no dedup is needed there
|
|
@@ -532,10 +562,8 @@ function _spannedCellCount(cellSize, aabb) {
|
|
|
532
562
|
const cy1 = _cellIndex(aabb.maxY, cellSize);
|
|
533
563
|
return (cx1 - cx0 + 1) * (cy1 - cy0 + 1);
|
|
534
564
|
}
|
|
535
|
-
// Diagnostics seam
|
|
536
|
-
//
|
|
537
|
-
// it through the null check. Not enabling guards costs one comparison per declined-or-overflowed
|
|
538
|
-
// insert — and nothing at all on the ordinary path.
|
|
565
|
+
// Diagnostics seam filled by setSpatialIndexingGuard. Caller-facing text stays in the separate
|
|
566
|
+
// formatSpatialIndexingNotice module, so production pays only the null checks at noteworthy sites.
|
|
539
567
|
let _indexingGuard = null;
|
|
540
568
|
// Reused scratch rectangles for the geometry overlap/containment helpers. Only ever read+written
|
|
541
569
|
// within a single non-nested helper call, so sharing them across the module allocates nothing per
|
package/dist/uniformGrid.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uniformGrid.js","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uniformGrid.js","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/spatial",
|
|
3
|
-
"version": "0.3.0-next.
|
|
3
|
+
"version": "0.3.0-next.1422.b585c0c",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@flighthq/geometry": "0.3.0-next.
|
|
40
|
-
"@flighthq/types": "0.3.0-next.
|
|
39
|
+
"@flighthq/geometry": "0.3.0-next.1422.b585c0c",
|
|
40
|
+
"@flighthq/types": "0.3.0-next.1422.b585c0c"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"typescript": "^5.3.0"
|
|
@@ -11,8 +11,10 @@ afterEach(() => {
|
|
|
11
11
|
describe('formatSpatialIndexingNotice', () => {
|
|
12
12
|
it('names the sentinel to check for a decline', () => {
|
|
13
13
|
const message = formatSpatialIndexingNotice({
|
|
14
|
+
cellSize: 10,
|
|
14
15
|
id: 3,
|
|
15
16
|
mode: 'declined',
|
|
17
|
+
operation: 'insert',
|
|
16
18
|
reason: 'non-finite-bounds',
|
|
17
19
|
wouldOccupyBucketCount: 0,
|
|
18
20
|
});
|
|
@@ -23,8 +25,10 @@ describe('formatSpatialIndexingNotice', () => {
|
|
|
23
25
|
|
|
24
26
|
it('names the span and the cell-size cause for an overflow, without calling it wrong', () => {
|
|
25
27
|
const message = formatSpatialIndexingNotice({
|
|
28
|
+
cellSize: 1,
|
|
26
29
|
id: 4,
|
|
27
30
|
mode: 'overflow',
|
|
31
|
+
operation: 'insert',
|
|
28
32
|
reason: null,
|
|
29
33
|
wouldOccupyBucketCount: 40000,
|
|
30
34
|
});
|
|
@@ -36,10 +40,50 @@ describe('formatSpatialIndexingNotice', () => {
|
|
|
36
40
|
expect(message).toContain('Results are unaffected');
|
|
37
41
|
});
|
|
38
42
|
|
|
43
|
+
it('explains invalid cell sizes, inverted bounds, and missing ids', () => {
|
|
44
|
+
expect(
|
|
45
|
+
formatSpatialIndexingNotice({
|
|
46
|
+
cellSize: 0,
|
|
47
|
+
id: 1,
|
|
48
|
+
mode: 'overflow',
|
|
49
|
+
operation: 'insert',
|
|
50
|
+
reason: 'invalid-cell-size',
|
|
51
|
+
wouldOccupyBucketCount: 0,
|
|
52
|
+
}),
|
|
53
|
+
).toContain('cellSize must be a positive finite number');
|
|
54
|
+
expect(
|
|
55
|
+
formatSpatialIndexingNotice({
|
|
56
|
+
cellSize: 10,
|
|
57
|
+
id: 2,
|
|
58
|
+
mode: 'declined',
|
|
59
|
+
operation: 'update',
|
|
60
|
+
reason: 'inverted-bounds',
|
|
61
|
+
wouldOccupyBucketCount: 0,
|
|
62
|
+
}),
|
|
63
|
+
).toContain('minX/minY must not exceed maxX/maxY');
|
|
64
|
+
expect(
|
|
65
|
+
formatSpatialIndexingNotice({
|
|
66
|
+
cellSize: 10,
|
|
67
|
+
id: 3,
|
|
68
|
+
mode: 'absent',
|
|
69
|
+
operation: 'remove',
|
|
70
|
+
reason: 'missing-id',
|
|
71
|
+
wouldOccupyBucketCount: 0,
|
|
72
|
+
}),
|
|
73
|
+
).toContain('removal was a no-op');
|
|
74
|
+
});
|
|
75
|
+
|
|
39
76
|
it('says plainly that a mode it does not cover carries no advice', () => {
|
|
40
|
-
expect(
|
|
41
|
-
|
|
42
|
-
|
|
77
|
+
expect(
|
|
78
|
+
formatSpatialIndexingNotice({
|
|
79
|
+
cellSize: 10,
|
|
80
|
+
id: 5,
|
|
81
|
+
mode: 'cells',
|
|
82
|
+
operation: 'insert',
|
|
83
|
+
reason: null,
|
|
84
|
+
wouldOccupyBucketCount: 4,
|
|
85
|
+
}),
|
|
86
|
+
).toContain('no caller-facing advice');
|
|
43
87
|
});
|
|
44
88
|
|
|
45
89
|
it('formats what the grid actually hands a guard', () => {
|
|
@@ -50,8 +94,22 @@ describe('formatSpatialIndexingNotice', () => {
|
|
|
50
94
|
grid.insertSpatialObject(9, { minX: 0, minY: 0, maxX: 199, maxY: 199 });
|
|
51
95
|
grid.insertSpatialObject(10, { minX: NaN, minY: 0, maxX: 1, maxY: 1 });
|
|
52
96
|
expect(notices.map(formatSpatialIndexingNotice)).toEqual([
|
|
53
|
-
formatSpatialIndexingNotice({
|
|
54
|
-
|
|
97
|
+
formatSpatialIndexingNotice({
|
|
98
|
+
cellSize: 1,
|
|
99
|
+
id: 9,
|
|
100
|
+
mode: 'overflow',
|
|
101
|
+
operation: 'insert',
|
|
102
|
+
reason: null,
|
|
103
|
+
wouldOccupyBucketCount: 40000,
|
|
104
|
+
}),
|
|
105
|
+
formatSpatialIndexingNotice({
|
|
106
|
+
cellSize: 1,
|
|
107
|
+
id: 10,
|
|
108
|
+
mode: 'declined',
|
|
109
|
+
operation: 'insert',
|
|
110
|
+
reason: 'non-finite-bounds',
|
|
111
|
+
wouldOccupyBucketCount: 0,
|
|
112
|
+
}),
|
|
55
113
|
]);
|
|
56
114
|
expect(notices.map(formatSpatialIndexingNotice)[0]).toContain('40000 cells');
|
|
57
115
|
});
|
package/src/uniformGrid.test.ts
CHANGED
|
@@ -17,6 +17,172 @@ function pairKeys(pairs: readonly SpatialPair[]): string[] {
|
|
|
17
17
|
return pairs.map((p) => `${Math.min(p.a, p.b)}-${Math.max(p.a, p.b)}`).sort();
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function bruteForcePairKeys(objects: ReadonlyMap<SpatialObjectId, Readonly<SpatialAabb>>, cellSize: number): string[] {
|
|
21
|
+
const entries = [...objects];
|
|
22
|
+
const pairs: string[] = [];
|
|
23
|
+
for (let i = 0; i < entries.length; i++) {
|
|
24
|
+
for (let j = i + 1; j < entries.length; j++) {
|
|
25
|
+
const [aId, a] = entries[i];
|
|
26
|
+
const [bId, b] = entries[j];
|
|
27
|
+
if (
|
|
28
|
+
isOverflowBounds(a, cellSize) || isOverflowBounds(b, cellSize)
|
|
29
|
+
? boundsOverlap(a, b)
|
|
30
|
+
: boundsShareCell(a, b, cellSize)
|
|
31
|
+
) {
|
|
32
|
+
pairs.push(`${Math.min(aId, bId)}-${Math.max(aId, bId)}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return pairs.sort();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function boundsContainPoint(bounds: Readonly<SpatialAabb>, x: number, y: number): boolean {
|
|
40
|
+
return x >= bounds.minX && x <= bounds.maxX && y >= bounds.minY && y <= bounds.maxY;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function boundsIntersectRay(bounds: Readonly<SpatialAabb>, ox: number, oy: number, dx: number, dy: number): boolean {
|
|
44
|
+
let tMin = -Infinity;
|
|
45
|
+
let tMax = Infinity;
|
|
46
|
+
if (dx === 0) {
|
|
47
|
+
if (ox < bounds.minX || ox > bounds.maxX) return false;
|
|
48
|
+
} else {
|
|
49
|
+
const tx0 = (bounds.minX - ox) / dx;
|
|
50
|
+
const tx1 = (bounds.maxX - ox) / dx;
|
|
51
|
+
tMin = Math.max(tMin, Math.min(tx0, tx1));
|
|
52
|
+
tMax = Math.min(tMax, Math.max(tx0, tx1));
|
|
53
|
+
}
|
|
54
|
+
if (dy === 0) {
|
|
55
|
+
if (oy < bounds.minY || oy > bounds.maxY) return false;
|
|
56
|
+
} else {
|
|
57
|
+
const ty0 = (bounds.minY - oy) / dy;
|
|
58
|
+
const ty1 = (bounds.maxY - oy) / dy;
|
|
59
|
+
tMin = Math.max(tMin, Math.min(ty0, ty1));
|
|
60
|
+
tMax = Math.min(tMax, Math.max(ty0, ty1));
|
|
61
|
+
}
|
|
62
|
+
return tMax >= tMin && tMax >= 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function boundsShareCell(a: Readonly<SpatialAabb>, b: Readonly<SpatialAabb>, cellSize: number): boolean {
|
|
66
|
+
return (
|
|
67
|
+
Math.max(Math.floor(a.minX / cellSize), Math.floor(b.minX / cellSize)) <=
|
|
68
|
+
Math.min(Math.floor(a.maxX / cellSize), Math.floor(b.maxX / cellSize)) &&
|
|
69
|
+
Math.max(Math.floor(a.minY / cellSize), Math.floor(b.minY / cellSize)) <=
|
|
70
|
+
Math.min(Math.floor(a.maxY / cellSize), Math.floor(b.maxY / cellSize))
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function createTestRandom(seed: number): () => number {
|
|
75
|
+
let state = seed >>> 0;
|
|
76
|
+
return () => {
|
|
77
|
+
state ^= state << 13;
|
|
78
|
+
state ^= state >>> 17;
|
|
79
|
+
state ^= state << 5;
|
|
80
|
+
return (state >>> 0) / 0x1_0000_0000;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function isOverflowBounds(bounds: Readonly<SpatialAabb>, cellSize: number): boolean {
|
|
85
|
+
const width = Math.floor(bounds.maxX / cellSize) - Math.floor(bounds.minX / cellSize) + 1;
|
|
86
|
+
const height = Math.floor(bounds.maxY / cellSize) - Math.floor(bounds.minY / cellSize) + 1;
|
|
87
|
+
return width * height > MAX_INDEXED_CELLS_PER_OBJECT;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function sortedIds(ids: readonly SpatialObjectId[]): SpatialObjectId[] {
|
|
91
|
+
return [...ids].sort((a, b) => a - b);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
describe('brute-force property coverage', () => {
|
|
95
|
+
it('matches pair, region, point, and ray oracles through seeded cell and overflow churn', () => {
|
|
96
|
+
const cellSize = 4;
|
|
97
|
+
for (const seed of [0x1357_9bdf, 0x2468_ace0, 0x5eed_f00d, 0xc0ff_ee42]) {
|
|
98
|
+
const random = createTestRandom(seed);
|
|
99
|
+
const grid = createUniformGridSpatialBackend(cellSize);
|
|
100
|
+
const objects = new Map<SpatialObjectId, SpatialAabb>();
|
|
101
|
+
|
|
102
|
+
function randomBounds(overflow: boolean): SpatialAabb {
|
|
103
|
+
const minX = Math.floor(random() * 160) - 80 + random();
|
|
104
|
+
const minY = Math.floor(random() * 160) - 80 + random();
|
|
105
|
+
const width = overflow ? cellSize * (34 + Math.floor(random() * 12)) : 0.25 + random() * 12;
|
|
106
|
+
const height = overflow ? cellSize * (34 + Math.floor(random() * 12)) : 0.25 + random() * 12;
|
|
107
|
+
return { minX, minY, maxX: minX + width, maxY: minY + height };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function expectMatchesBruteForce(label: string): void {
|
|
111
|
+
const pairs: SpatialPair[] = [];
|
|
112
|
+
grid.querySpatialPairs(pairs);
|
|
113
|
+
expect(pairKeys(pairs), `${label}: pairs`).toEqual(bruteForcePairKeys(objects, cellSize));
|
|
114
|
+
|
|
115
|
+
const regionMinX = random() * 240 - 120;
|
|
116
|
+
const regionMinY = random() * 240 - 120;
|
|
117
|
+
const region: SpatialAabb = {
|
|
118
|
+
minX: regionMinX,
|
|
119
|
+
minY: regionMinY,
|
|
120
|
+
maxX: regionMinX + 1 + random() * 80,
|
|
121
|
+
maxY: regionMinY + 1 + random() * 80,
|
|
122
|
+
};
|
|
123
|
+
const regionActual: SpatialObjectId[] = [];
|
|
124
|
+
grid.querySpatialRegion(region, regionActual);
|
|
125
|
+
const regionExpected = [...objects].filter(([, bounds]) => boundsOverlap(bounds, region)).map(([id]) => id);
|
|
126
|
+
expect(sortedIds(regionActual), `${label}: region`).toEqual(sortedIds(regionExpected));
|
|
127
|
+
|
|
128
|
+
const pointX = random() * 320 - 160;
|
|
129
|
+
const pointY = random() * 320 - 160;
|
|
130
|
+
const pointActual: SpatialObjectId[] = [];
|
|
131
|
+
grid.querySpatialPoint(pointX, pointY, pointActual);
|
|
132
|
+
const pointExpected = [...objects]
|
|
133
|
+
.filter(([, bounds]) => boundsContainPoint(bounds, pointX, pointY))
|
|
134
|
+
.map(([id]) => id);
|
|
135
|
+
expect(sortedIds(pointActual), `${label}: point`).toEqual(sortedIds(pointExpected));
|
|
136
|
+
|
|
137
|
+
const rayX = random() * 400 - 200;
|
|
138
|
+
const rayY = random() * 400 - 200;
|
|
139
|
+
let rayDx = random() * 2 - 1;
|
|
140
|
+
let rayDy = random() * 2 - 1;
|
|
141
|
+
if (random() < 0.1) rayDx = 0;
|
|
142
|
+
if (random() < 0.1) rayDy = 0;
|
|
143
|
+
const rayActual: SpatialObjectId[] = [];
|
|
144
|
+
grid.querySpatialRay(rayX, rayY, rayDx, rayDy, rayActual);
|
|
145
|
+
const rayExpected = [...objects]
|
|
146
|
+
.filter(([, bounds]) => boundsIntersectRay(bounds, rayX, rayY, rayDx, rayDy))
|
|
147
|
+
.map(([id]) => id);
|
|
148
|
+
expect(sortedIds(rayActual), `${label}: ray`).toEqual(sortedIds(rayExpected));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const ordinary = randomBounds(false);
|
|
152
|
+
objects.set(0, ordinary);
|
|
153
|
+
grid.insertSpatialObject(0, ordinary);
|
|
154
|
+
expectMatchesBruteForce(`seed ${seed}, ordinary`);
|
|
155
|
+
|
|
156
|
+
const overflow = randomBounds(true);
|
|
157
|
+
objects.set(0, overflow);
|
|
158
|
+
grid.updateSpatialObject(0, overflow);
|
|
159
|
+
expect(grid.explainSpatialIndexing(0).mode).toBe('overflow');
|
|
160
|
+
expectMatchesBruteForce(`seed ${seed}, overflow`);
|
|
161
|
+
|
|
162
|
+
const ordinaryAgain = randomBounds(false);
|
|
163
|
+
objects.set(0, ordinaryAgain);
|
|
164
|
+
grid.updateSpatialObject(0, ordinaryAgain);
|
|
165
|
+
expect(grid.explainSpatialIndexing(0).mode).toBe('cells');
|
|
166
|
+
expectMatchesBruteForce(`seed ${seed}, cells again`);
|
|
167
|
+
|
|
168
|
+
for (let step = 0; step < 100; step++) {
|
|
169
|
+
const id = Math.floor(random() * 18);
|
|
170
|
+
if (random() < 0.72) {
|
|
171
|
+
const bounds = randomBounds(random() < 0.22);
|
|
172
|
+
if (objects.has(id)) grid.updateSpatialObject(id, bounds);
|
|
173
|
+
else if (random() < 0.5) grid.insertSpatialObject(id, bounds);
|
|
174
|
+
else grid.updateSpatialObject(id, bounds);
|
|
175
|
+
objects.set(id, bounds);
|
|
176
|
+
} else {
|
|
177
|
+
grid.removeSpatialObject(id);
|
|
178
|
+
objects.delete(id);
|
|
179
|
+
}
|
|
180
|
+
expectMatchesBruteForce(`seed ${seed}, step ${step}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
20
186
|
describe('cell range across every transition that can strand it', () => {
|
|
21
187
|
// Chief's class-not-instance rule applied to the ray-hang defect. The bug was never "removal after
|
|
22
188
|
// overflow"; it was that a separately-maintained `empty` flag could disagree with the cells it
|
|
@@ -460,13 +626,49 @@ describe('oversized-extent bound', () => {
|
|
|
460
626
|
});
|
|
461
627
|
});
|
|
462
628
|
|
|
629
|
+
describe('ray edge cases', () => {
|
|
630
|
+
it('finds objects along a ray that passes exactly through cell corners', () => {
|
|
631
|
+
const grid = createUniformGridSpatialBackend(10);
|
|
632
|
+
grid.insertSpatialObject(1, { minX: 10, minY: 10, maxX: 12, maxY: 12 });
|
|
633
|
+
grid.insertSpatialObject(2, { minX: 20, minY: 20, maxX: 22, maxY: 22 });
|
|
634
|
+
const out: SpatialObjectId[] = [];
|
|
635
|
+
grid.querySpatialRay(-5, -5, 1, 1, out);
|
|
636
|
+
expect(sortedIds(out)).toEqual([1, 2]);
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
it('finds an object when the ray starts inside its bounds', () => {
|
|
640
|
+
const grid = createUniformGridSpatialBackend(10);
|
|
641
|
+
grid.insertSpatialObject(1, { minX: 5, minY: 5, maxX: 15, maxY: 15 });
|
|
642
|
+
const out: SpatialObjectId[] = [];
|
|
643
|
+
grid.querySpatialRay(10, 10, -1, 0, out);
|
|
644
|
+
expect(out).toEqual([1]);
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
it('clips a ray entering the occupied range from far outside', () => {
|
|
648
|
+
const grid = createUniformGridSpatialBackend(10);
|
|
649
|
+
grid.insertSpatialObject(1, { minX: 100, minY: 30, maxX: 110, maxY: 40 });
|
|
650
|
+
const out: SpatialObjectId[] = [];
|
|
651
|
+
grid.querySpatialRay(-1e9, 35, 1, 0, out);
|
|
652
|
+
expect(out).toEqual([1]);
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
|
|
463
656
|
describe('setSpatialIndexingGuard', () => {
|
|
464
657
|
it('reports a decline with its reason, and no span', () => {
|
|
465
658
|
const notices: SpatialIndexingNotice[] = [];
|
|
466
659
|
setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
|
|
467
660
|
const grid = createUniformGridSpatialBackend(10);
|
|
468
661
|
grid.insertSpatialObject(7, { minX: NaN, minY: 0, maxX: 10, maxY: 10 });
|
|
469
|
-
expect(notices).toEqual([
|
|
662
|
+
expect(notices).toEqual([
|
|
663
|
+
{
|
|
664
|
+
cellSize: 10,
|
|
665
|
+
id: 7,
|
|
666
|
+
mode: 'declined',
|
|
667
|
+
operation: 'insert',
|
|
668
|
+
reason: 'non-finite-bounds',
|
|
669
|
+
wouldOccupyBucketCount: 0,
|
|
670
|
+
},
|
|
671
|
+
]);
|
|
470
672
|
});
|
|
471
673
|
|
|
472
674
|
it('reports an overflow with the span the bound refused to walk', () => {
|
|
@@ -474,7 +676,87 @@ describe('setSpatialIndexingGuard', () => {
|
|
|
474
676
|
setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
|
|
475
677
|
const grid = createUniformGridSpatialBackend(1);
|
|
476
678
|
grid.insertSpatialObject(7, { minX: 0, minY: 0, maxX: 199, maxY: 199 });
|
|
477
|
-
expect(notices).toEqual([
|
|
679
|
+
expect(notices).toEqual([
|
|
680
|
+
{
|
|
681
|
+
cellSize: 1,
|
|
682
|
+
id: 7,
|
|
683
|
+
mode: 'overflow',
|
|
684
|
+
operation: 'insert',
|
|
685
|
+
reason: null,
|
|
686
|
+
wouldOccupyBucketCount: 40000,
|
|
687
|
+
},
|
|
688
|
+
]);
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
it('reports an invalid cell size and keeps results correct through the bounded overflow path', () => {
|
|
692
|
+
const notices: SpatialIndexingNotice[] = [];
|
|
693
|
+
setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
|
|
694
|
+
for (const cellSize of [0, -1]) {
|
|
695
|
+
const grid = createUniformGridSpatialBackend(cellSize);
|
|
696
|
+
expect(grid.insertSpatialObject(7, { minX: 0, minY: 0, maxX: 10, maxY: 10 })).toBe(true);
|
|
697
|
+
const point: SpatialObjectId[] = [];
|
|
698
|
+
grid.querySpatialPoint(5, 5, point);
|
|
699
|
+
expect(point).toEqual([7]);
|
|
700
|
+
}
|
|
701
|
+
expect(notices).toEqual(
|
|
702
|
+
[0, -1].map((cellSize) => ({
|
|
703
|
+
cellSize,
|
|
704
|
+
id: 7,
|
|
705
|
+
mode: 'overflow',
|
|
706
|
+
operation: 'insert',
|
|
707
|
+
reason: 'invalid-cell-size',
|
|
708
|
+
wouldOccupyBucketCount: 0,
|
|
709
|
+
})),
|
|
710
|
+
);
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
it('declines and reports inverted bounds', () => {
|
|
714
|
+
const notices: SpatialIndexingNotice[] = [];
|
|
715
|
+
setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
|
|
716
|
+
const grid = createUniformGridSpatialBackend(10);
|
|
717
|
+
expect(grid.insertSpatialObject(7, { minX: 10, minY: 0, maxX: 0, maxY: 10 })).toBe(false);
|
|
718
|
+
expect(grid.explainSpatialIndexing(7)).toEqual({
|
|
719
|
+
bucketCount: 0,
|
|
720
|
+
id: 7,
|
|
721
|
+
mode: 'declined',
|
|
722
|
+
reason: 'inverted-bounds',
|
|
723
|
+
});
|
|
724
|
+
expect(notices).toEqual([
|
|
725
|
+
{
|
|
726
|
+
cellSize: 10,
|
|
727
|
+
id: 7,
|
|
728
|
+
mode: 'declined',
|
|
729
|
+
operation: 'insert',
|
|
730
|
+
reason: 'inverted-bounds',
|
|
731
|
+
wouldOccupyBucketCount: 0,
|
|
732
|
+
},
|
|
733
|
+
]);
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
it('reports update and remove operations whose id was never inserted', () => {
|
|
737
|
+
const notices: SpatialIndexingNotice[] = [];
|
|
738
|
+
setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
|
|
739
|
+
const grid = createUniformGridSpatialBackend(10);
|
|
740
|
+
expect(grid.updateSpatialObject(7, { minX: 0, minY: 0, maxX: 5, maxY: 5 })).toBe(true);
|
|
741
|
+
grid.removeSpatialObject(8);
|
|
742
|
+
expect(notices).toEqual([
|
|
743
|
+
{
|
|
744
|
+
cellSize: 10,
|
|
745
|
+
id: 7,
|
|
746
|
+
mode: 'cells',
|
|
747
|
+
operation: 'update',
|
|
748
|
+
reason: 'missing-id',
|
|
749
|
+
wouldOccupyBucketCount: 0,
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
cellSize: 10,
|
|
753
|
+
id: 8,
|
|
754
|
+
mode: 'absent',
|
|
755
|
+
operation: 'remove',
|
|
756
|
+
reason: 'missing-id',
|
|
757
|
+
wouldOccupyBucketCount: 0,
|
|
758
|
+
},
|
|
759
|
+
]);
|
|
478
760
|
});
|
|
479
761
|
|
|
480
762
|
it('stays silent on the ordinary path', () => {
|