hyper-scatter 0.1.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/LICENSE +21 -0
- package/README.md +142 -0
- package/dist-lib/controller/interaction_controller.d.ts +29 -0
- package/dist-lib/controller/interaction_controller.d.ts.map +1 -0
- package/dist-lib/controller/interaction_controller.js +286 -0
- package/dist-lib/controller/interaction_controller.js.map +1 -0
- package/dist-lib/core/dataset.d.ts +62 -0
- package/dist-lib/core/dataset.d.ts.map +1 -0
- package/dist-lib/core/dataset.js +152 -0
- package/dist-lib/core/dataset.js.map +1 -0
- package/dist-lib/core/lasso_simplify.d.ts +16 -0
- package/dist-lib/core/lasso_simplify.d.ts.map +1 -0
- package/dist-lib/core/lasso_simplify.js +173 -0
- package/dist-lib/core/lasso_simplify.js.map +1 -0
- package/dist-lib/core/math/euclidean.d.ts +31 -0
- package/dist-lib/core/math/euclidean.d.ts.map +1 -0
- package/dist-lib/core/math/euclidean.js +64 -0
- package/dist-lib/core/math/euclidean.js.map +1 -0
- package/dist-lib/core/math/poincare.d.ts +117 -0
- package/dist-lib/core/math/poincare.d.ts.map +1 -0
- package/dist-lib/core/math/poincare.js +321 -0
- package/dist-lib/core/math/poincare.js.map +1 -0
- package/dist-lib/core/rng.d.ts +18 -0
- package/dist-lib/core/rng.d.ts.map +1 -0
- package/dist-lib/core/rng.js +52 -0
- package/dist-lib/core/rng.js.map +1 -0
- package/dist-lib/core/selection/point_in_polygon.d.ts +30 -0
- package/dist-lib/core/selection/point_in_polygon.d.ts.map +1 -0
- package/dist-lib/core/selection/point_in_polygon.js +112 -0
- package/dist-lib/core/selection/point_in_polygon.js.map +1 -0
- package/dist-lib/core/types.d.ts +185 -0
- package/dist-lib/core/types.d.ts.map +1 -0
- package/dist-lib/core/types.js +53 -0
- package/dist-lib/core/types.js.map +1 -0
- package/dist-lib/impl_candidate/spatial_index.d.ts +45 -0
- package/dist-lib/impl_candidate/spatial_index.d.ts.map +1 -0
- package/dist-lib/impl_candidate/spatial_index.js +186 -0
- package/dist-lib/impl_candidate/spatial_index.js.map +1 -0
- package/dist-lib/impl_candidate/webgl_candidate.d.ts +283 -0
- package/dist-lib/impl_candidate/webgl_candidate.d.ts.map +1 -0
- package/dist-lib/impl_candidate/webgl_candidate.js +2276 -0
- package/dist-lib/impl_candidate/webgl_candidate.js.map +1 -0
- package/dist-lib/index.d.ts +11 -0
- package/dist-lib/index.d.ts.map +1 -0
- package/dist-lib/index.js +52 -0
- package/dist-lib/index.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types and contracts for the viz-lab.
|
|
3
|
+
* Both reference and candidate implementations must satisfy these interfaces.
|
|
4
|
+
*/
|
|
5
|
+
export interface Dataset {
|
|
6
|
+
/** Number of points */
|
|
7
|
+
n: number;
|
|
8
|
+
/** Interleaved x,y coordinates: [x0, y0, x1, y1, ...] length = 2*n */
|
|
9
|
+
positions: Float32Array;
|
|
10
|
+
/** Label for each point (for coloring) */
|
|
11
|
+
labels: Uint16Array;
|
|
12
|
+
/** Geometry mode */
|
|
13
|
+
geometry: GeometryMode;
|
|
14
|
+
}
|
|
15
|
+
export type GeometryMode = 'euclidean' | 'poincare';
|
|
16
|
+
/** Euclidean view state: simple pan + zoom */
|
|
17
|
+
export interface EuclideanViewState {
|
|
18
|
+
type: 'euclidean';
|
|
19
|
+
/** Center of view in data coordinates */
|
|
20
|
+
centerX: number;
|
|
21
|
+
centerY: number;
|
|
22
|
+
/** Zoom level (1 = no zoom, >1 = zoomed in) */
|
|
23
|
+
zoom: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Hyperbolic view state using Mobius transformation.
|
|
27
|
+
* The isometry is represented as translation by a point in the disk.
|
|
28
|
+
* Camera transform: z -> (z - a) / (1 - conj(a) * z) where a = (ax, ay)
|
|
29
|
+
*/
|
|
30
|
+
export interface HyperbolicViewState {
|
|
31
|
+
type: 'poincare';
|
|
32
|
+
/** Translation point x-coordinate (in Poincare disk, |a| < 1) */
|
|
33
|
+
ax: number;
|
|
34
|
+
/** Translation point y-coordinate */
|
|
35
|
+
ay: number;
|
|
36
|
+
/** Display zoom scalar (purely visual, applied after Mobius) */
|
|
37
|
+
displayZoom: number;
|
|
38
|
+
}
|
|
39
|
+
export type ViewState = EuclideanViewState | HyperbolicViewState;
|
|
40
|
+
export interface Modifiers {
|
|
41
|
+
shift: boolean;
|
|
42
|
+
ctrl: boolean;
|
|
43
|
+
alt: boolean;
|
|
44
|
+
meta: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface HitResult {
|
|
47
|
+
index: number;
|
|
48
|
+
screenX: number;
|
|
49
|
+
screenY: number;
|
|
50
|
+
distance: number;
|
|
51
|
+
}
|
|
52
|
+
/** Axis-aligned bounds in 2D data coordinates. */
|
|
53
|
+
export interface Bounds2D {
|
|
54
|
+
xMin: number;
|
|
55
|
+
yMin: number;
|
|
56
|
+
xMax: number;
|
|
57
|
+
yMax: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Geometry-based selection shape in data coordinates.
|
|
61
|
+
* Allows implementations to defer index enumeration.
|
|
62
|
+
*/
|
|
63
|
+
export interface SelectionGeometry {
|
|
64
|
+
type: 'polygon';
|
|
65
|
+
/** Polygon vertices in data coordinates: [x0, y0, x1, y1, ...] */
|
|
66
|
+
coords: Float32Array;
|
|
67
|
+
/** Optional AABB bounds of coords for fast prefiltering (same coordinate space as coords). */
|
|
68
|
+
bounds?: Bounds2D;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Result of a lasso/selection operation.
|
|
72
|
+
*
|
|
73
|
+
* Implementations may return either:
|
|
74
|
+
* - kind: 'indices' with a Set<number> of selected point indices
|
|
75
|
+
* - kind: 'geometry' with the selection shape in data coordinates
|
|
76
|
+
*
|
|
77
|
+
* Both kinds must provide a has() method for membership testing.
|
|
78
|
+
*/
|
|
79
|
+
export interface SelectionResult {
|
|
80
|
+
/** How the selection is represented */
|
|
81
|
+
kind: 'indices' | 'geometry';
|
|
82
|
+
/** For kind === 'indices': the selected point indices */
|
|
83
|
+
indices?: Set<number>;
|
|
84
|
+
/** For kind === 'geometry': selection shape in data coordinates */
|
|
85
|
+
geometry?: SelectionGeometry;
|
|
86
|
+
/** Time to compute the selection */
|
|
87
|
+
computeTimeMs: number;
|
|
88
|
+
/**
|
|
89
|
+
* Test if a point index is in the selection.
|
|
90
|
+
* Required for all kinds - enables correctness verification.
|
|
91
|
+
*/
|
|
92
|
+
has(index: number): boolean;
|
|
93
|
+
}
|
|
94
|
+
export type InteractionMode = 'pan' | 'lasso';
|
|
95
|
+
export interface InitOptions {
|
|
96
|
+
width: number;
|
|
97
|
+
height: number;
|
|
98
|
+
devicePixelRatio?: number;
|
|
99
|
+
backgroundColor?: string;
|
|
100
|
+
pointRadius?: number;
|
|
101
|
+
colors?: string[];
|
|
102
|
+
/** Optional styling overrides for the hyperbolic (Poincaré) disk backdrop. */
|
|
103
|
+
poincareDiskFillColor?: string;
|
|
104
|
+
poincareDiskBorderColor?: string;
|
|
105
|
+
poincareGridColor?: string;
|
|
106
|
+
poincareDiskBorderWidthPx?: number;
|
|
107
|
+
poincareGridWidthPx?: number;
|
|
108
|
+
}
|
|
109
|
+
export interface Renderer {
|
|
110
|
+
/** Initialize the renderer with a canvas */
|
|
111
|
+
init(canvas: HTMLCanvasElement, opts: InitOptions): void;
|
|
112
|
+
/** Set the dataset to render */
|
|
113
|
+
setDataset(dataset: Dataset): void;
|
|
114
|
+
/** Set the current view state */
|
|
115
|
+
setView(view: ViewState): void;
|
|
116
|
+
/** Get the current view state */
|
|
117
|
+
getView(): ViewState;
|
|
118
|
+
/** Render the current frame */
|
|
119
|
+
render(): void;
|
|
120
|
+
/** Handle canvas resize */
|
|
121
|
+
resize(width: number, height: number): void;
|
|
122
|
+
/** Set selected point indices */
|
|
123
|
+
setSelection(indices: Set<number>): void;
|
|
124
|
+
/** Get current selection */
|
|
125
|
+
getSelection(): Set<number>;
|
|
126
|
+
/** Set hovered point index (-1 for none) */
|
|
127
|
+
setHovered(index: number): void;
|
|
128
|
+
/** Clean up resources */
|
|
129
|
+
destroy(): void;
|
|
130
|
+
/** Pan the view (in screen pixels) */
|
|
131
|
+
pan(deltaX: number, deltaY: number, modifiers: Modifiers): void;
|
|
132
|
+
/** Zoom at anchor point (wheel delta, positive = zoom in) */
|
|
133
|
+
zoom(anchorX: number, anchorY: number, delta: number, modifiers: Modifiers): void;
|
|
134
|
+
/** Hit test at screen coordinates */
|
|
135
|
+
hitTest(screenX: number, screenY: number): HitResult | null;
|
|
136
|
+
/** Lasso selection with screen-space polyline */
|
|
137
|
+
lassoSelect(polyline: Float32Array): SelectionResult;
|
|
138
|
+
/**
|
|
139
|
+
* Count the number of points selected by a SelectionResult.
|
|
140
|
+
*
|
|
141
|
+
* Motivation: geometry-based (predicate) selections are fast to create, but
|
|
142
|
+
* naively counting them by scanning all N points in the UI is too slow.
|
|
143
|
+
* Implementations should use any available spatial index / backend to count
|
|
144
|
+
* efficiently.
|
|
145
|
+
*/
|
|
146
|
+
countSelection(result: SelectionResult, opts?: CountSelectionOptions): Promise<number>;
|
|
147
|
+
/** Project a data point to screen coordinates */
|
|
148
|
+
projectToScreen(dataX: number, dataY: number): {
|
|
149
|
+
x: number;
|
|
150
|
+
y: number;
|
|
151
|
+
};
|
|
152
|
+
/** Unproject screen coordinates to data space */
|
|
153
|
+
unprojectFromScreen(screenX: number, screenY: number): {
|
|
154
|
+
x: number;
|
|
155
|
+
y: number;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
export interface CountSelectionOptions {
|
|
159
|
+
/** Optional cancellation predicate (return true to abort early). */
|
|
160
|
+
shouldCancel?: () => boolean;
|
|
161
|
+
/** Optional progress callback for long-running counts. */
|
|
162
|
+
onProgress?: (selectedCount: number, processedCandidates: number) => void;
|
|
163
|
+
/**
|
|
164
|
+
* Time slice budget (ms). If > 0, counting yields back to the browser after
|
|
165
|
+
* roughly this amount of work to keep the UI responsive.
|
|
166
|
+
*
|
|
167
|
+
* Set to 0 to run synchronously without yielding (useful for benchmarks).
|
|
168
|
+
* Default: 8ms.
|
|
169
|
+
*/
|
|
170
|
+
yieldEveryMs?: number;
|
|
171
|
+
}
|
|
172
|
+
export declare const DEFAULT_COLORS: string[];
|
|
173
|
+
export declare const SELECTION_COLOR = "#ff0000";
|
|
174
|
+
export declare const HOVER_COLOR = "#ffffff";
|
|
175
|
+
/**
|
|
176
|
+
* Create a SelectionResult from a Set of indices.
|
|
177
|
+
* Convenience helper for implementations that compute indices directly.
|
|
178
|
+
*/
|
|
179
|
+
export declare function createIndicesSelectionResult(indices: Set<number>, computeTimeMs: number): SelectionResult;
|
|
180
|
+
/**
|
|
181
|
+
* Create a SelectionResult from geometry and a positions array.
|
|
182
|
+
* The has() method tests point membership against the polygon.
|
|
183
|
+
*/
|
|
184
|
+
export declare function createGeometrySelectionResult(geometry: SelectionGeometry, positions: Float32Array, computeTimeMs: number, pointInPolygonFn: (px: number, py: number, polygon: Float32Array) => boolean): SelectionResult;
|
|
185
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types and contracts for the viz-lab.
|
|
3
|
+
* Both reference and candidate implementations must satisfy these interfaces.
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Default Colors (categorical palette)
|
|
7
|
+
// ============================================================================
|
|
8
|
+
export const DEFAULT_COLORS = [
|
|
9
|
+
'#4e79a7', // blue
|
|
10
|
+
'#f28e2c', // orange
|
|
11
|
+
'#e15759', // red
|
|
12
|
+
'#76b7b2', // teal
|
|
13
|
+
'#59a14f', // green
|
|
14
|
+
'#edc949', // yellow
|
|
15
|
+
'#af7aa1', // purple
|
|
16
|
+
'#ff9da7', // pink
|
|
17
|
+
'#9c755f', // brown
|
|
18
|
+
'#bab0ab', // gray
|
|
19
|
+
];
|
|
20
|
+
export const SELECTION_COLOR = '#ff0000';
|
|
21
|
+
export const HOVER_COLOR = '#ffffff';
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Selection Result Helpers
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Create a SelectionResult from a Set of indices.
|
|
27
|
+
* Convenience helper for implementations that compute indices directly.
|
|
28
|
+
*/
|
|
29
|
+
export function createIndicesSelectionResult(indices, computeTimeMs) {
|
|
30
|
+
return {
|
|
31
|
+
kind: 'indices',
|
|
32
|
+
indices,
|
|
33
|
+
computeTimeMs,
|
|
34
|
+
has: (index) => indices.has(index),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a SelectionResult from geometry and a positions array.
|
|
39
|
+
* The has() method tests point membership against the polygon.
|
|
40
|
+
*/
|
|
41
|
+
export function createGeometrySelectionResult(geometry, positions, computeTimeMs, pointInPolygonFn) {
|
|
42
|
+
return {
|
|
43
|
+
kind: 'geometry',
|
|
44
|
+
geometry,
|
|
45
|
+
computeTimeMs,
|
|
46
|
+
has: (index) => {
|
|
47
|
+
const x = positions[index * 2];
|
|
48
|
+
const y = positions[index * 2 + 1];
|
|
49
|
+
return pointInPolygonFn(x, y, geometry.coords);
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2NH,+EAA+E;AAC/E,uCAAuC;AACvC,+EAA+E;AAE/E,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS,EAAE,OAAO;IAClB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,OAAO;IAClB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,OAAO;IAClB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,OAAO;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC;AACzC,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAAoB,EACpB,aAAqB;IAErB,OAAO;QACL,IAAI,EAAE,SAAS;QACf,OAAO;QACP,aAAa;QACb,GAAG,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAC3C,QAA2B,EAC3B,SAAuB,EACvB,aAAqB,EACrB,gBAA4E;IAE5E,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ;QACR,aAAa;QACb,GAAG,EAAE,CAAC,KAAa,EAAE,EAAE;YACrB,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACnC,OAAO,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spatial indexing helpers for fast hit-testing and lasso selection.
|
|
3
|
+
*
|
|
4
|
+
* Design goals:
|
|
5
|
+
* - Deterministic and exact (matches reference semantics).
|
|
6
|
+
* - No allocations in tight loops where practical.
|
|
7
|
+
* - Works for both Euclidean and Poincaré datasets.
|
|
8
|
+
*/
|
|
9
|
+
interface Bounds2D {
|
|
10
|
+
minX: number;
|
|
11
|
+
minY: number;
|
|
12
|
+
maxX: number;
|
|
13
|
+
maxY: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Static uniform grid over a set of 2D points.
|
|
17
|
+
*
|
|
18
|
+
* This index is intended to be built once per dataset (data-space) and reused
|
|
19
|
+
* across view changes. It supports fast AABB queries and radius queries.
|
|
20
|
+
*/
|
|
21
|
+
export declare class UniformGridIndex {
|
|
22
|
+
readonly n: number;
|
|
23
|
+
readonly bounds: Bounds2D;
|
|
24
|
+
readonly cellsX: number;
|
|
25
|
+
readonly cellsY: number;
|
|
26
|
+
readonly cellSizeX: number;
|
|
27
|
+
readonly cellSizeY: number;
|
|
28
|
+
/** offsets.length = cellsX*cellsY + 1 */
|
|
29
|
+
readonly offsets: Uint32Array;
|
|
30
|
+
/** ids.length = n (point indices packed per cell) */
|
|
31
|
+
readonly ids: Uint32Array;
|
|
32
|
+
constructor(positions: Float32Array, bounds?: Bounds2D, targetPointsPerCell?: number);
|
|
33
|
+
/**
|
|
34
|
+
* Iterate all point ids in cells overlapping the given AABB.
|
|
35
|
+
*
|
|
36
|
+
* This avoids allocating or filling a potentially enormous `out` array.
|
|
37
|
+
* It is especially important for large-N lasso selection benchmarks where
|
|
38
|
+
* the polygon AABB can cover many cells.
|
|
39
|
+
*/
|
|
40
|
+
forEachInAABB(minX: number, minY: number, maxX: number, maxY: number, visit: (id: number) => void): void;
|
|
41
|
+
queryRadius(x: number, y: number, r: number, out: number[]): void;
|
|
42
|
+
}
|
|
43
|
+
export declare function lassoSelectIndexed(positions: Float32Array, polygonDataSpace: Float32Array, index: UniformGridIndex): Set<number>;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=spatial_index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spatial_index.d.ts","sourceRoot":"","sources":["../../src/impl_candidate/spatial_index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AA2CD;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAE1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,qDAAqD;IACrD,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;gBAEd,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,mBAAmB,SAAK;IA6DhF;;;;;;OAMG;IACH,aAAa,CACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAC1B,IAAI;IAsBP,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI;CAIlE;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,EACvB,gBAAgB,EAAE,YAAY,EAC9B,KAAK,EAAE,gBAAgB,GACtB,GAAG,CAAC,MAAM,CAAC,CA+Bb"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spatial indexing helpers for fast hit-testing and lasso selection.
|
|
3
|
+
*
|
|
4
|
+
* Design goals:
|
|
5
|
+
* - Deterministic and exact (matches reference semantics).
|
|
6
|
+
* - No allocations in tight loops where practical.
|
|
7
|
+
* - Works for both Euclidean and Poincaré datasets.
|
|
8
|
+
*/
|
|
9
|
+
import { pointInPolygon } from '../core/selection/point_in_polygon.js';
|
|
10
|
+
function clampInt(v, lo, hi) {
|
|
11
|
+
if (v < lo)
|
|
12
|
+
return lo;
|
|
13
|
+
if (v > hi)
|
|
14
|
+
return hi;
|
|
15
|
+
return v | 0;
|
|
16
|
+
}
|
|
17
|
+
function clamp(v, lo, hi) {
|
|
18
|
+
return Math.max(lo, Math.min(hi, v));
|
|
19
|
+
}
|
|
20
|
+
function computeBounds(positions) {
|
|
21
|
+
let minX = Infinity;
|
|
22
|
+
let minY = Infinity;
|
|
23
|
+
let maxX = -Infinity;
|
|
24
|
+
let maxY = -Infinity;
|
|
25
|
+
for (let i = 0; i < positions.length; i += 2) {
|
|
26
|
+
const x = positions[i];
|
|
27
|
+
const y = positions[i + 1];
|
|
28
|
+
if (x < minX)
|
|
29
|
+
minX = x;
|
|
30
|
+
if (x > maxX)
|
|
31
|
+
maxX = x;
|
|
32
|
+
if (y < minY)
|
|
33
|
+
minY = y;
|
|
34
|
+
if (y > maxY)
|
|
35
|
+
maxY = y;
|
|
36
|
+
}
|
|
37
|
+
if (!Number.isFinite(minX) || !Number.isFinite(minY)) {
|
|
38
|
+
return { minX: 0, minY: 0, maxX: 0, maxY: 0 };
|
|
39
|
+
}
|
|
40
|
+
// Avoid degenerate ranges.
|
|
41
|
+
const eps = 1e-9;
|
|
42
|
+
if (Math.abs(maxX - minX) < eps) {
|
|
43
|
+
maxX = minX + 1;
|
|
44
|
+
}
|
|
45
|
+
if (Math.abs(maxY - minY) < eps) {
|
|
46
|
+
maxY = minY + 1;
|
|
47
|
+
}
|
|
48
|
+
return { minX, minY, maxX, maxY };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Static uniform grid over a set of 2D points.
|
|
52
|
+
*
|
|
53
|
+
* This index is intended to be built once per dataset (data-space) and reused
|
|
54
|
+
* across view changes. It supports fast AABB queries and radius queries.
|
|
55
|
+
*/
|
|
56
|
+
export class UniformGridIndex {
|
|
57
|
+
n;
|
|
58
|
+
bounds;
|
|
59
|
+
cellsX;
|
|
60
|
+
cellsY;
|
|
61
|
+
cellSizeX;
|
|
62
|
+
cellSizeY;
|
|
63
|
+
/** offsets.length = cellsX*cellsY + 1 */
|
|
64
|
+
offsets;
|
|
65
|
+
/** ids.length = n (point indices packed per cell) */
|
|
66
|
+
ids;
|
|
67
|
+
constructor(positions, bounds, targetPointsPerCell = 64) {
|
|
68
|
+
this.n = (positions.length / 2) | 0;
|
|
69
|
+
this.bounds = bounds ?? computeBounds(positions);
|
|
70
|
+
const spanX = this.bounds.maxX - this.bounds.minX;
|
|
71
|
+
const spanY = this.bounds.maxY - this.bounds.minY;
|
|
72
|
+
// Choose cell count so average occupancy is ~targetPointsPerCell.
|
|
73
|
+
// totalCells ~= n / target
|
|
74
|
+
const totalCells = clamp(Math.ceil(this.n / Math.max(1, targetPointsPerCell)), 64, 1_000_000);
|
|
75
|
+
// Split cells across axes proportionally to aspect ratio.
|
|
76
|
+
const aspect = spanX / spanY;
|
|
77
|
+
let cellsX = Math.round(Math.sqrt(totalCells * aspect));
|
|
78
|
+
cellsX = clampInt(cellsX, 8, 2048);
|
|
79
|
+
let cellsY = Math.round(totalCells / cellsX);
|
|
80
|
+
cellsY = clampInt(cellsY, 8, 2048);
|
|
81
|
+
this.cellsX = cellsX;
|
|
82
|
+
this.cellsY = cellsY;
|
|
83
|
+
this.cellSizeX = spanX / cellsX;
|
|
84
|
+
this.cellSizeY = spanY / cellsY;
|
|
85
|
+
const cellCount = cellsX * cellsY;
|
|
86
|
+
const counts = new Uint32Array(cellCount);
|
|
87
|
+
// 1) Count points per cell
|
|
88
|
+
for (let i = 0; i < this.n; i++) {
|
|
89
|
+
const x = positions[i * 2];
|
|
90
|
+
const y = positions[i * 2 + 1];
|
|
91
|
+
const cx = clampInt(Math.floor((x - this.bounds.minX) / this.cellSizeX), 0, cellsX - 1);
|
|
92
|
+
const cy = clampInt(Math.floor((y - this.bounds.minY) / this.cellSizeY), 0, cellsY - 1);
|
|
93
|
+
counts[cy * cellsX + cx]++;
|
|
94
|
+
}
|
|
95
|
+
// 2) Prefix sums to offsets
|
|
96
|
+
const offsets = new Uint32Array(cellCount + 1);
|
|
97
|
+
let acc = 0;
|
|
98
|
+
for (let c = 0; c < cellCount; c++) {
|
|
99
|
+
offsets[c] = acc;
|
|
100
|
+
acc += counts[c];
|
|
101
|
+
}
|
|
102
|
+
offsets[cellCount] = acc;
|
|
103
|
+
// 3) Fill ids via running cursor
|
|
104
|
+
const cursor = offsets.slice(0, cellCount);
|
|
105
|
+
const ids = new Uint32Array(this.n);
|
|
106
|
+
for (let i = 0; i < this.n; i++) {
|
|
107
|
+
const x = positions[i * 2];
|
|
108
|
+
const y = positions[i * 2 + 1];
|
|
109
|
+
const cx = clampInt(Math.floor((x - this.bounds.minX) / this.cellSizeX), 0, cellsX - 1);
|
|
110
|
+
const cy = clampInt(Math.floor((y - this.bounds.minY) / this.cellSizeY), 0, cellsY - 1);
|
|
111
|
+
const cell = cy * cellsX + cx;
|
|
112
|
+
const dst = cursor[cell]++;
|
|
113
|
+
ids[dst] = i;
|
|
114
|
+
}
|
|
115
|
+
this.offsets = offsets;
|
|
116
|
+
this.ids = ids;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Iterate all point ids in cells overlapping the given AABB.
|
|
120
|
+
*
|
|
121
|
+
* This avoids allocating or filling a potentially enormous `out` array.
|
|
122
|
+
* It is especially important for large-N lasso selection benchmarks where
|
|
123
|
+
* the polygon AABB can cover many cells.
|
|
124
|
+
*/
|
|
125
|
+
forEachInAABB(minX, minY, maxX, maxY, visit) {
|
|
126
|
+
const eps = 1e-12;
|
|
127
|
+
minX -= eps;
|
|
128
|
+
minY -= eps;
|
|
129
|
+
maxX += eps;
|
|
130
|
+
maxY += eps;
|
|
131
|
+
const cx0 = clampInt(Math.floor((minX - this.bounds.minX) / this.cellSizeX), 0, this.cellsX - 1);
|
|
132
|
+
const cy0 = clampInt(Math.floor((minY - this.bounds.minY) / this.cellSizeY), 0, this.cellsY - 1);
|
|
133
|
+
const cx1 = clampInt(Math.floor((maxX - this.bounds.minX) / this.cellSizeX), 0, this.cellsX - 1);
|
|
134
|
+
const cy1 = clampInt(Math.floor((maxY - this.bounds.minY) / this.cellSizeY), 0, this.cellsY - 1);
|
|
135
|
+
for (let cy = cy0; cy <= cy1; cy++) {
|
|
136
|
+
const rowBase = cy * this.cellsX;
|
|
137
|
+
for (let cx = cx0; cx <= cx1; cx++) {
|
|
138
|
+
const cell = rowBase + cx;
|
|
139
|
+
const start = this.offsets[cell];
|
|
140
|
+
const end = this.offsets[cell + 1];
|
|
141
|
+
for (let k = start; k < end; k++) {
|
|
142
|
+
visit(this.ids[k]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
queryRadius(x, y, r, out) {
|
|
148
|
+
out.length = 0;
|
|
149
|
+
this.forEachInAABB(x - r, y - r, x + r, y + r, (id) => out.push(id));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
export function lassoSelectIndexed(positions, polygonDataSpace, index) {
|
|
153
|
+
const result = new Set();
|
|
154
|
+
const nPoly = polygonDataSpace.length / 2;
|
|
155
|
+
if (nPoly < 3)
|
|
156
|
+
return result;
|
|
157
|
+
let minX = Infinity;
|
|
158
|
+
let minY = Infinity;
|
|
159
|
+
let maxX = -Infinity;
|
|
160
|
+
let maxY = -Infinity;
|
|
161
|
+
for (let i = 0; i < polygonDataSpace.length; i += 2) {
|
|
162
|
+
const x = polygonDataSpace[i];
|
|
163
|
+
const y = polygonDataSpace[i + 1];
|
|
164
|
+
if (x < minX)
|
|
165
|
+
minX = x;
|
|
166
|
+
if (x > maxX)
|
|
167
|
+
maxX = x;
|
|
168
|
+
if (y < minY)
|
|
169
|
+
minY = y;
|
|
170
|
+
if (y > maxY)
|
|
171
|
+
maxY = y;
|
|
172
|
+
}
|
|
173
|
+
// For very large datasets, avoid building a huge candidates list.
|
|
174
|
+
// Iterate overlapping cells directly.
|
|
175
|
+
index.forEachInAABB(minX, minY, maxX, maxY, (i) => {
|
|
176
|
+
const x = positions[i * 2];
|
|
177
|
+
const y = positions[i * 2 + 1];
|
|
178
|
+
if (x < minX || x > maxX || y < minY || y > maxY)
|
|
179
|
+
return;
|
|
180
|
+
if (pointInPolygon(x, y, polygonDataSpace)) {
|
|
181
|
+
result.add(i);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=spatial_index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spatial_index.js","sourceRoot":"","sources":["../../src/impl_candidate/spatial_index.ts"],"names":[],"mappings":"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"}
|