@buley/hexgrid-3d 1.0.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.
Files changed (46) hide show
  1. package/.eslintrc.json +28 -0
  2. package/LICENSE +39 -0
  3. package/README.md +291 -0
  4. package/examples/basic-usage.tsx +52 -0
  5. package/package.json +65 -0
  6. package/public/hexgrid-worker.js +1763 -0
  7. package/rust/Cargo.toml +41 -0
  8. package/rust/src/lib.rs +740 -0
  9. package/rust/src/math.rs +574 -0
  10. package/rust/src/spatial.rs +245 -0
  11. package/rust/src/statistics.rs +496 -0
  12. package/src/HexGridEnhanced.ts +16 -0
  13. package/src/Snapshot.ts +1402 -0
  14. package/src/adapters.ts +65 -0
  15. package/src/algorithms/AdvancedStatistics.ts +328 -0
  16. package/src/algorithms/BayesianStatistics.ts +317 -0
  17. package/src/algorithms/FlowField.ts +126 -0
  18. package/src/algorithms/FluidSimulation.ts +99 -0
  19. package/src/algorithms/GraphAlgorithms.ts +184 -0
  20. package/src/algorithms/OutlierDetection.ts +391 -0
  21. package/src/algorithms/ParticleSystem.ts +85 -0
  22. package/src/algorithms/index.ts +13 -0
  23. package/src/compat.ts +96 -0
  24. package/src/components/HexGrid.tsx +31 -0
  25. package/src/components/NarrationOverlay.tsx +221 -0
  26. package/src/components/index.ts +2 -0
  27. package/src/features.ts +125 -0
  28. package/src/index.ts +30 -0
  29. package/src/math/HexCoordinates.ts +15 -0
  30. package/src/math/Matrix4.ts +35 -0
  31. package/src/math/Quaternion.ts +37 -0
  32. package/src/math/SpatialIndex.ts +114 -0
  33. package/src/math/Vector3.ts +69 -0
  34. package/src/math/index.ts +11 -0
  35. package/src/note-adapter.ts +124 -0
  36. package/src/ontology-adapter.ts +77 -0
  37. package/src/stores/index.ts +1 -0
  38. package/src/stores/uiStore.ts +85 -0
  39. package/src/types/index.ts +3 -0
  40. package/src/types.ts +152 -0
  41. package/src/utils/image-utils.ts +25 -0
  42. package/src/wasm/HexGridWasmWrapper.ts +753 -0
  43. package/src/wasm/index.ts +7 -0
  44. package/src/workers/hexgrid-math.ts +177 -0
  45. package/src/workers/hexgrid-worker.worker.ts +1807 -0
  46. package/tsconfig.json +18 -0
@@ -0,0 +1,7 @@
1
+ /**
2
+ * WASM Module Exports
3
+ *
4
+ * @module wasm
5
+ */
6
+
7
+ export * from './HexGridWasmWrapper'
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Pure mathematical functions for hexgrid calculations.
3
+ * These functions have NO side effects, NO logging, and NO mutable state access.
4
+ * They are deterministic and testable in isolation.
5
+ */
6
+
7
+ /**
8
+ * Calculate the bounding box of a set of 2D/3D positions.
9
+ * @pure - No side effects, deterministic
10
+ * @param positions Array of [x, y, z] coordinates
11
+ * @returns Object with min/max bounds and dimensions
12
+ */
13
+ export function getGridBounds(positions: [number, number, number][]) {
14
+ if (!positions || positions.length === 0) {
15
+ return { minX: 0, maxX: 0, minY: 0, maxY: 0, width: 0, height: 0 }
16
+ }
17
+
18
+ let minX = Infinity,
19
+ maxX = -Infinity,
20
+ minY = Infinity,
21
+ maxY = -Infinity
22
+
23
+ for (const p of positions) {
24
+ if (!p) continue
25
+ minX = Math.min(minX, p[0])
26
+ maxX = Math.max(maxX, p[0])
27
+ minY = Math.min(minY, p[1])
28
+ maxY = Math.max(maxY, p[1])
29
+ }
30
+
31
+ return { minX, maxX, minY, maxY, width: maxX - minX, height: maxY - minY }
32
+ }
33
+
34
+ /**
35
+ * Calculate Euclidean distance between two 3D points with optional spherical wrapping.
36
+ * @pure - No side effects, deterministic
37
+ * @param a First point [x, y, z]
38
+ * @param b Second point [x, y, z]
39
+ * @param bounds Grid bounds for spherical calculation
40
+ * @param isSpherical Whether to apply spherical wrapping (toroidal distance)
41
+ * @returns Euclidean distance
42
+ */
43
+ export function distanceBetween(
44
+ a: [number, number, number],
45
+ b: [number, number, number],
46
+ bounds: { width: number; height: number },
47
+ isSpherical: boolean
48
+ ): number {
49
+ let dx = b[0] - a[0]
50
+ let dy = b[1] - a[1]
51
+
52
+ if (isSpherical && bounds.width > 0 && bounds.height > 0) {
53
+ // Apply toroidal wrapping: shortest distance considering wraparound
54
+ if (Math.abs(dx) > bounds.width / 2) {
55
+ dx = dx > 0 ? dx - bounds.width : dx + bounds.width
56
+ }
57
+ if (Math.abs(dy) > bounds.height / 2) {
58
+ dy = dy > 0 ? dy - bounds.height : dy + bounds.height
59
+ }
60
+ }
61
+
62
+ return Math.sqrt(dx * dx + dy * dy)
63
+ }
64
+
65
+ /**
66
+ * Calculate UV texture coordinates for a tile based on its grid position.
67
+ * @pure - No side effects, deterministic
68
+ * @param gridCol Column index (0-based)
69
+ * @param gridRow Row index (0-based)
70
+ * @param tilesX Total number of columns in texture grid
71
+ * @param tilesY Total number of rows in texture grid
72
+ * @returns [minU, minV, maxU, maxV] in range [0, 1]
73
+ *
74
+ * Note: V=1.0 represents the top of the texture.
75
+ * Row 0 maps to top, so maxV=1 and minV=1-1/tilesY.
76
+ */
77
+ export function calculateUvBoundsFromGridPosition(
78
+ gridCol: number,
79
+ gridRow: number,
80
+ tilesX: number,
81
+ tilesY: number
82
+ ): [number, number, number, number] {
83
+ // Guard against invalid grid dimensions
84
+ if (tilesX <= 0 || tilesY <= 0) {
85
+ return [0, 0, 1, 1]
86
+ }
87
+
88
+ const minU = gridCol / tilesX
89
+ const maxU = (gridCol + 1) / tilesX
90
+ // V=1 is top, so row 0 maps to top (maxV=1, minV=1-1/tilesY)
91
+ const minV = 1 - (gridRow + 1) / tilesY
92
+ const maxV = 1 - gridRow / tilesY
93
+
94
+ return [minU, minV, maxU, maxV]
95
+ }
96
+
97
+ /**
98
+ * Calculate contiguity score between indices (internal connectivity).
99
+ * Higher score means more indices in the set are neighbors with each other.
100
+ * @pure - No side effects, deterministic
101
+ * @param indices Set of position indices to measure
102
+ * @param positions Array of all positions
103
+ * @param hexRadius Radius for neighbor detection
104
+ * @param getNeighbors Function to get neighbors for an index (dependency injection)
105
+ * @returns Sum of neighbor connections within the set
106
+ */
107
+ export function calculateContiguity(
108
+ indices: number[],
109
+ positions: [number, number, number][],
110
+ hexRadius: number,
111
+ getNeighbors: (index: number) => number[]
112
+ ): number {
113
+ if (!indices || indices.length === 0) return 0
114
+ if (!positions || positions.length === 0) return 0
115
+ if (hexRadius <= 0) return 0
116
+
117
+ const set = new Set(indices)
118
+ let total = 0
119
+
120
+ for (const idx of indices) {
121
+ const neighbors = getNeighbors(idx)
122
+ for (const n of neighbors) {
123
+ if (set.has(n)) total++
124
+ }
125
+ }
126
+
127
+ return total
128
+ }
129
+
130
+ /**
131
+ * Calculate contiguity score for a photo's indices.
132
+ * @pure - No side effects, deterministic
133
+ * @param indices Indices belonging to a photo
134
+ * @param positions Array of all positions
135
+ * @param hexRadius Radius for neighbor detection
136
+ * @param getNeighbors Function to get neighbors for an index
137
+ * @returns Total contiguity score
138
+ */
139
+ export function calculatePhotoContiguity(
140
+ indices: number[],
141
+ positions: [number, number, number][],
142
+ hexRadius: number,
143
+ getNeighbors: (index: number) => number[]
144
+ ): number {
145
+ return calculateContiguity(indices, positions, hexRadius, getNeighbors)
146
+ }
147
+
148
+ /**
149
+ * Calculate contiguity after a hypothetical swap of two indices.
150
+ * @pure - No side effects, deterministic
151
+ * @param indices Current indices
152
+ * @param positions Array of all positions
153
+ * @param hexRadius Radius for neighbor detection
154
+ * @param fromIndex Index to swap from
155
+ * @param toIndex Index to swap to
156
+ * @param getNeighbors Function to get neighbors for an index
157
+ * @returns Contiguity score after swap
158
+ */
159
+ export function calculateSwappedContiguity(
160
+ indices: number[],
161
+ positions: [number, number, number][],
162
+ hexRadius: number,
163
+ fromIndex: number,
164
+ toIndex: number,
165
+ getNeighbors: (index: number) => number[]
166
+ ): number {
167
+ if (!indices || indices.length === 0) return 0
168
+
169
+ const tempIndices = [...indices]
170
+ const fromPos = tempIndices.indexOf(fromIndex)
171
+ const toPos = tempIndices.indexOf(toIndex)
172
+
173
+ if (fromPos !== -1) tempIndices[fromPos] = toIndex
174
+ if (toPos !== -1) tempIndices[toPos] = fromIndex
175
+
176
+ return calculatePhotoContiguity(tempIndices, positions, hexRadius, getNeighbors)
177
+ }