midgard-hex-grid 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +308 -2
  3. package/demo/demo-minimal.ts +531 -0
  4. package/demo/demo-theory.ts +1679 -0
  5. package/demo/index.html +11 -0
  6. package/demo/minimal.html +11 -0
  7. package/demo/package-lock.json +1162 -0
  8. package/demo/package.json +11 -0
  9. package/demo/vite.config.ts +9 -0
  10. package/dist/c-r-fill-around.d.ts +19 -0
  11. package/dist/c-r-fill-around.d.ts.map +1 -0
  12. package/dist/c-r-fill-around.js +28 -0
  13. package/dist/c-r-fill-around.js.map +1 -0
  14. package/dist/c-r-skeleton.d.ts +18 -0
  15. package/dist/c-r-skeleton.d.ts.map +1 -0
  16. package/dist/c-r-skeleton.js +32 -0
  17. package/dist/c-r-skeleton.js.map +1 -0
  18. package/dist/c-r-validation.d.ts +16 -0
  19. package/dist/c-r-validation.d.ts.map +1 -0
  20. package/dist/c-r-validation.js +30 -0
  21. package/dist/c-r-validation.js.map +1 -0
  22. package/dist/coordinate-layer.d.ts +42 -0
  23. package/dist/coordinate-layer.d.ts.map +1 -0
  24. package/dist/coordinate-layer.js +67 -0
  25. package/dist/coordinate-layer.js.map +1 -0
  26. package/dist/coordinate-positioner.d.ts +33 -0
  27. package/dist/coordinate-positioner.d.ts.map +1 -0
  28. package/dist/coordinate-positioner.js +69 -0
  29. package/dist/coordinate-positioner.js.map +1 -0
  30. package/dist/coordinate-range-fill.d.ts +35 -0
  31. package/dist/coordinate-range-fill.d.ts.map +1 -0
  32. package/dist/coordinate-range-fill.js +83 -0
  33. package/dist/coordinate-range-fill.js.map +1 -0
  34. package/dist/coordinate-range.d.ts +78 -0
  35. package/dist/coordinate-range.d.ts.map +1 -0
  36. package/dist/coordinate-range.js +80 -0
  37. package/dist/coordinate-range.js.map +1 -0
  38. package/dist/coordinate.d.ts +30 -0
  39. package/dist/coordinate.d.ts.map +1 -0
  40. package/dist/coordinate.js +40 -0
  41. package/dist/coordinate.js.map +1 -0
  42. package/dist/g-bounds.d.ts +25 -0
  43. package/dist/g-bounds.d.ts.map +1 -0
  44. package/dist/g-bounds.js +51 -0
  45. package/dist/g-bounds.js.map +1 -0
  46. package/dist/g-x-dominated.d.ts +19 -0
  47. package/dist/g-x-dominated.d.ts.map +1 -0
  48. package/dist/g-x-dominated.js +54 -0
  49. package/dist/g-x-dominated.js.map +1 -0
  50. package/dist/g-y-dominated.d.ts +19 -0
  51. package/dist/g-y-dominated.d.ts.map +1 -0
  52. package/dist/g-y-dominated.js +54 -0
  53. package/dist/g-y-dominated.js.map +1 -0
  54. package/dist/geometry.d.ts +49 -0
  55. package/dist/geometry.d.ts.map +1 -0
  56. package/dist/geometry.js +79 -0
  57. package/dist/geometry.js.map +1 -0
  58. package/dist/h-g-bounds.d.ts +29 -0
  59. package/dist/h-g-bounds.d.ts.map +1 -0
  60. package/dist/h-g-bounds.js +39 -0
  61. package/dist/h-g-bounds.js.map +1 -0
  62. package/dist/h-g-hexagon.d.ts +50 -0
  63. package/dist/h-g-hexagon.d.ts.map +1 -0
  64. package/dist/h-g-hexagon.js +60 -0
  65. package/dist/h-g-hexagon.js.map +1 -0
  66. package/dist/hex-grid.d.ts +153 -0
  67. package/dist/hex-grid.d.ts.map +1 -0
  68. package/dist/hex-grid.js +186 -0
  69. package/dist/hex-grid.js.map +1 -0
  70. package/dist/index.d.ts +16 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +10 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/neighbours.d.ts +26 -0
  75. package/dist/neighbours.d.ts.map +1 -0
  76. package/dist/neighbours.js +119 -0
  77. package/dist/neighbours.js.map +1 -0
  78. package/dist/orientation.d.ts +8 -0
  79. package/dist/orientation.d.ts.map +1 -0
  80. package/dist/orientation.js +2 -0
  81. package/dist/orientation.js.map +1 -0
  82. package/docs/images/minimal-x.png +0 -0
  83. package/docs/images/minimal-y.png +0 -0
  84. package/docs/images/theory-x.png +0 -0
  85. package/docs/images/theory-y.png +0 -0
  86. package/package.json +21 -4
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Niklas Herrloff
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,309 @@
1
- # Temporary Holding Version
1
+ # Midgard Hex Grid
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Midgard Hex Grid is a small reusable TypeScript library for creating and working with hexagonal grids.
4
+
5
+ The library supports both x-dominated and y-dominated hex grids and handles the coordinate system, neighbour calculations, positioning and hexagon geometry. Its purpose is to let another programmer work with hexagonal grids without having to implement these calculations themselves.
6
+
7
+ ## Features
8
+
9
+ - Create x-dominated and y-dominated hex grids
10
+ - Create a single hexagon
11
+ - Generate complete grids from a rectangular skeleton
12
+ - Calculate the six neighbours of a coordinate
13
+ - Validate Midgard coordinates
14
+ - Calculate center positions
15
+ - Calculate the six corner points of a hexagon
16
+ - Calculate the outer bounds of a grid
17
+ - Generate coordinate ranges
18
+ - Generate layered coordinates with z-index values for rendering
19
+
20
+ ## Requirements
21
+
22
+ - TypeScript
23
+ - JavaScript environment with ES modules
24
+
25
+ The library has no runtime dependencies.
26
+
27
+ Development uses:
28
+
29
+ - TypeScript 7
30
+ - Vitest 5
31
+
32
+ ## Installation
33
+
34
+ Clone the repository and install the development dependencies:
35
+
36
+ ```bash
37
+ npm install
38
+ ```
39
+
40
+ Build the library:
41
+
42
+ ```bash
43
+ npm run build
44
+ ```
45
+
46
+ The compiled JavaScript and TypeScript declarations are generated in the `dist` directory.
47
+
48
+ ## Basic usage
49
+
50
+ The main class is `HexGrid`.
51
+
52
+ Create a grid by first choosing its orientation:
53
+
54
+ ```ts
55
+ import { HexGrid } from './dist/index.js'
56
+
57
+ const grid = new HexGrid('x-dominated')
58
+ ```
59
+
60
+ The orientation can be:
61
+
62
+ ```ts
63
+ 'x-dominated'
64
+ ```
65
+
66
+ or:
67
+
68
+ ```ts
69
+ 'y-dominated'
70
+ ```
71
+
72
+ ### Create a single hexagon
73
+
74
+ ```ts
75
+ const grid = new HexGrid('x-dominated')
76
+
77
+ const hexagon = grid.createSingleHexagon({
78
+ hexDiameter: 100
79
+ })
80
+ ```
81
+
82
+ The returned hexagon contains:
83
+
84
+ - its Midgard coordinate
85
+ - its center position
86
+ - its six corner points
87
+
88
+ These values can, for example, be used by an application to render the hexagon as SVG.
89
+
90
+ ### Create a complete grid
91
+
92
+ ```ts
93
+ const grid = new HexGrid('x-dominated')
94
+
95
+ const hexagons = grid.createGrid({
96
+ hexDiameter: 100,
97
+ skeletonWidth: 3,
98
+ skeletonHeight: 2
99
+ })
100
+ ```
101
+
102
+ `skeletonWidth` and `skeletonHeight` describe the rectangular skeleton around which the complete grid is generated.
103
+
104
+ The library automatically fills the surrounding coordinates and returns the hexagons in rendering order with calculated z-index values.
105
+
106
+ ### Y-dominated grid
107
+
108
+ The same API can be used for the other orientation:
109
+
110
+ ```ts
111
+ const grid = new HexGrid('y-dominated')
112
+
113
+ const hexagons = grid.createGrid({
114
+ hexDiameter: 100,
115
+ skeletonWidth: 3,
116
+ skeletonHeight: 2
117
+ })
118
+ ```
119
+
120
+ The grid orientation controls the coordinate relationships, positioning and geometry internally.
121
+
122
+ ## Neighbours
123
+
124
+ The six neighbouring coordinates can be calculated through the grid:
125
+
126
+ ```ts
127
+ const neighbours = grid.getNeighbours({
128
+ x: 2,
129
+ y: 2
130
+ })
131
+ ```
132
+
133
+ The result depends on whether the `HexGrid` is x-dominated or y-dominated.
134
+
135
+ ## Coordinate validation
136
+
137
+ A coordinate can be checked before it is used:
138
+
139
+ ```ts
140
+ const valid = grid.isValidCoordinate({
141
+ x: 2,
142
+ y: 2
143
+ })
144
+ ```
145
+
146
+ ## Lower-level API
147
+
148
+ `HexGrid` provides the simplest interface for most uses.
149
+
150
+ The library also exports lower-level classes for programmers who want to work directly with individual parts of the grid system, including:
151
+
152
+ - `CoordinateValidator`
153
+ - `NeighbourCalculator`
154
+ - `HexagonGeometry`
155
+ - `CoordinatePositioner`
156
+ - `CoordinateRange`
157
+ - `CoordinateRangeFiller`
158
+ - `CoordinateLayer`
159
+
160
+ The public TypeScript types are exported from `src/index.ts`.
161
+
162
+ ## Testing
163
+
164
+ The mathematical and coordinate logic is tested with automated unit tests using Vitest.
165
+
166
+ Run all automated tests with:
167
+
168
+ ```bash
169
+ npx vitest run
170
+ ```
171
+
172
+ The library is also tested visually with a separate graphical Test-App. This makes it possible to verify that the calculated coordinates and geometry produce the expected SVG hexagons and grid layouts.
173
+
174
+ See [`TEST_REPORT.md`](./TEST_REPORT.md) for the test documentation and results.
175
+
176
+ ## Development commands
177
+
178
+ Check the TypeScript code without producing build files:
179
+
180
+ ```bash
181
+ npm run check
182
+ ```
183
+
184
+ Build the library:
185
+
186
+ ```bash
187
+ npm run build
188
+ ```
189
+
190
+ Run the automated tests:
191
+
192
+ ```bash
193
+ npx vitest run
194
+ ```
195
+
196
+ ## Version
197
+
198
+ Current version: `1.0.0`
199
+
200
+ The version is also available from the library:
201
+
202
+ ```ts
203
+ import { MIDGARD_HEX_GRID_VERSION } from './dist/index.js'
204
+ ```
205
+
206
+ ## License
207
+
208
+ ISC
209
+
210
+ ## Visual Demonstrations
211
+
212
+ Midgard Hex Grid includes two complementary demonstrations.
213
+
214
+ The Minimal Demonstration shows how little TypeScript is needed to create a grid. The Theory Demonstration explains the coordinate system: parity, the skeleton, and the two orientations.
215
+
216
+ ### Minimal Demonstration
217
+
218
+ A grid is created with `new HexGrid()` and `createGrid()`. Each example below sets `hexDiameter` to 120 and uses `skeletonWidth: 2` and `skeletonHeight: 2`. For an X-dominated grid, `hexDiameter` is the hexagon's width. For a Y-dominated grid, it is the hexagon's height.
219
+
220
+ `createGrid()` builds the complete grid around the skeleton and fills in the surrounding hexagons. These examples produce 17 hexagons. The four light coastal-blue hexagons are the skeleton, at (2,2), (4,2), (2,4), and (4,4). The cream hexagons are the surrounding fill. Both orientations use the same logical coordinates. Only the geometry changes.
221
+
222
+ **X-dominated Hex Grid**
223
+
224
+ ![X-dominated grid of 17 pointy-top hexagons. The skeleton hexagons (2,2), (4,2), (2,4), and (4,4) are light coastal blue and labeled. The createXDominatedGrid example is shown beside the grid.](docs/images/minimal-x.png)
225
+
226
+ **Y-dominated Hex Grid**
227
+
228
+ ![Y-dominated grid of 17 flat-top hexagons. The same skeleton coordinates (2,2), (4,2), (2,4), and (4,4) are light coastal blue and labeled. The createYDominatedGrid example is shown beside the grid.](docs/images/minimal-y.png)
229
+
230
+ The functions below are the examples used by the Minimal Demonstration. Import `HexGrid` as shown in [Basic usage](#basic-usage).
231
+
232
+ ```ts
233
+ import { HexGrid } from './dist/index.js'
234
+
235
+ function createXDominatedGrid() {
236
+ const hexDiameter = 120
237
+ const hexGrid = new HexGrid('x-dominated')
238
+
239
+ const hexagons = hexGrid.createGrid({
240
+ hexDiameter,
241
+ skeletonWidth: 2,
242
+ skeletonHeight: 2
243
+ })
244
+
245
+ return hexagons
246
+ }
247
+ ```
248
+
249
+ ```ts
250
+ import { HexGrid } from './dist/index.js'
251
+
252
+ function createYDominatedGrid() {
253
+ const hexDiameter = 120
254
+ const hexGrid = new HexGrid('y-dominated')
255
+
256
+ const hexagons = hexGrid.createGrid({
257
+ hexDiameter,
258
+ skeletonWidth: 2,
259
+ skeletonHeight: 2
260
+ })
261
+
262
+ return hexagons
263
+ }
264
+ ```
265
+
266
+ ### Theory Demonstration
267
+
268
+ The diagrams below show how a rectangular coordinate field becomes a hexagonal grid, and which movements are valid.
269
+
270
+ #### Coordinate parity
271
+
272
+ A valid Midgard coordinate is two even numbers, such as (2,2) or (4,4), or two odd numbers, such as (3,3) or (1,5). A mixed coordinate, such as (3,4), is invalid because its numbers have different parity.
273
+
274
+ #### The skeleton foundation
275
+
276
+ (2,2) is always the top-left skeleton hexagon. Every skeleton begins there, whatever the grid's size or orientation. A 1 × 1 skeleton contains only (2,2) as its skeleton hexagon. Increasing `skeletonWidth` or `skeletonHeight` extends the skeleton from that origin through further even coordinates, such as (4,2), (2,4), and (4,4).
277
+
278
+ #### Grid orientation
279
+
280
+ An X-dominated grid uses hexagons with pointed tops and bottoms. A Y-dominated grid uses hexagons with flat tops and bottoms. Both orientations follow the same parity rules, so a coordinate such as (2,2) keeps its logical identity when the geometry changes.
281
+
282
+ **X-dominated — Coordinate System and Neighbour Movement**
283
+
284
+ ![X-dominated theory diagram. A rectangular coordinate field stands beside a pointy-top hex grid, showing the six valid neighbours of the center and the forbidden vertical movements.](docs/images/theory-x.png)
285
+
286
+ The left figure maps the rectangular coordinates onto the hexagons. The right figure shows the six valid neighbours of the center hexagon and marks movement in the Y direction as forbidden.
287
+
288
+ **Y-dominated — Coordinate System and Neighbour Movement**
289
+
290
+ ![Y-dominated theory diagram. A rectangular coordinate field stands beside a flat-top hex grid, showing the six valid neighbours of the center and the forbidden horizontal movements.](docs/images/theory-y.png)
291
+
292
+ The same relationship holds for the Y-dominated orientation. The forbidden movements are in the X direction.
293
+
294
+ ### Explore the Demonstrations
295
+
296
+ The rendered pages are not published at a separate public address. The source of each page is in this repository:
297
+
298
+ - [Minimal Demonstration](demo/minimal.html)
299
+ - [Theory Demonstration](demo/index.html)
300
+
301
+ To run them locally, install the demo dependencies and start Vite from the `demo` directory. The `dev` script in `demo/package.json` runs `vite`.
302
+
303
+ ```bash
304
+ cd demo
305
+ npm install
306
+ npm run dev
307
+ ```
308
+
309
+ Vite prints a local address. The Theory Demonstration is `demo/index.html`, served at `/`. The Minimal Demonstration is `demo/minimal.html`.