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.
- package/LICENSE +15 -0
- package/README.md +308 -2
- package/demo/demo-minimal.ts +531 -0
- package/demo/demo-theory.ts +1679 -0
- package/demo/index.html +11 -0
- package/demo/minimal.html +11 -0
- package/demo/package-lock.json +1162 -0
- package/demo/package.json +11 -0
- package/demo/vite.config.ts +9 -0
- package/dist/c-r-fill-around.d.ts +19 -0
- package/dist/c-r-fill-around.d.ts.map +1 -0
- package/dist/c-r-fill-around.js +28 -0
- package/dist/c-r-fill-around.js.map +1 -0
- package/dist/c-r-skeleton.d.ts +18 -0
- package/dist/c-r-skeleton.d.ts.map +1 -0
- package/dist/c-r-skeleton.js +32 -0
- package/dist/c-r-skeleton.js.map +1 -0
- package/dist/c-r-validation.d.ts +16 -0
- package/dist/c-r-validation.d.ts.map +1 -0
- package/dist/c-r-validation.js +30 -0
- package/dist/c-r-validation.js.map +1 -0
- package/dist/coordinate-layer.d.ts +42 -0
- package/dist/coordinate-layer.d.ts.map +1 -0
- package/dist/coordinate-layer.js +67 -0
- package/dist/coordinate-layer.js.map +1 -0
- package/dist/coordinate-positioner.d.ts +33 -0
- package/dist/coordinate-positioner.d.ts.map +1 -0
- package/dist/coordinate-positioner.js +69 -0
- package/dist/coordinate-positioner.js.map +1 -0
- package/dist/coordinate-range-fill.d.ts +35 -0
- package/dist/coordinate-range-fill.d.ts.map +1 -0
- package/dist/coordinate-range-fill.js +83 -0
- package/dist/coordinate-range-fill.js.map +1 -0
- package/dist/coordinate-range.d.ts +78 -0
- package/dist/coordinate-range.d.ts.map +1 -0
- package/dist/coordinate-range.js +80 -0
- package/dist/coordinate-range.js.map +1 -0
- package/dist/coordinate.d.ts +30 -0
- package/dist/coordinate.d.ts.map +1 -0
- package/dist/coordinate.js +40 -0
- package/dist/coordinate.js.map +1 -0
- package/dist/g-bounds.d.ts +25 -0
- package/dist/g-bounds.d.ts.map +1 -0
- package/dist/g-bounds.js +51 -0
- package/dist/g-bounds.js.map +1 -0
- package/dist/g-x-dominated.d.ts +19 -0
- package/dist/g-x-dominated.d.ts.map +1 -0
- package/dist/g-x-dominated.js +54 -0
- package/dist/g-x-dominated.js.map +1 -0
- package/dist/g-y-dominated.d.ts +19 -0
- package/dist/g-y-dominated.d.ts.map +1 -0
- package/dist/g-y-dominated.js +54 -0
- package/dist/g-y-dominated.js.map +1 -0
- package/dist/geometry.d.ts +49 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +79 -0
- package/dist/geometry.js.map +1 -0
- package/dist/h-g-bounds.d.ts +29 -0
- package/dist/h-g-bounds.d.ts.map +1 -0
- package/dist/h-g-bounds.js +39 -0
- package/dist/h-g-bounds.js.map +1 -0
- package/dist/h-g-hexagon.d.ts +50 -0
- package/dist/h-g-hexagon.d.ts.map +1 -0
- package/dist/h-g-hexagon.js +60 -0
- package/dist/h-g-hexagon.js.map +1 -0
- package/dist/hex-grid.d.ts +153 -0
- package/dist/hex-grid.d.ts.map +1 -0
- package/dist/hex-grid.js +186 -0
- package/dist/hex-grid.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/neighbours.d.ts +26 -0
- package/dist/neighbours.d.ts.map +1 -0
- package/dist/neighbours.js +119 -0
- package/dist/neighbours.js.map +1 -0
- package/dist/orientation.d.ts +8 -0
- package/dist/orientation.d.ts.map +1 -0
- package/dist/orientation.js +2 -0
- package/dist/orientation.js.map +1 -0
- package/docs/images/minimal-x.png +0 -0
- package/docs/images/minimal-y.png +0 -0
- package/docs/images/theory-x.png +0 -0
- package/docs/images/theory-y.png +0 -0
- 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
|
-
#
|
|
1
|
+
# Midgard Hex Grid
|
|
2
2
|
|
|
3
|
-
|
|
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
|
+

|
|
225
|
+
|
|
226
|
+
**Y-dominated Hex Grid**
|
|
227
|
+
|
|
228
|
+

|
|
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
|
+

|
|
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
|
+

|
|
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`.
|