midgard-hex-grid 0.0.0-stage → 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.
- package/LICENSE +15 -0
- package/README.md +207 -2
- 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 +52 -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 +49 -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 +54 -0
- package/dist/coordinate-range-fill.d.ts.map +1 -0
- package/dist/coordinate-range-fill.js +81 -0
- package/dist/coordinate-range-fill.js.map +1 -0
- package/dist/coordinate-range.d.ts +69 -0
- package/dist/coordinate-range.d.ts.map +1 -0
- package/dist/coordinate-range.js +63 -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 +73 -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 +26 -0
- package/dist/h-g-bounds.d.ts.map +1 -0
- package/dist/h-g-bounds.js +37 -0
- package/dist/h-g-bounds.js.map +1 -0
- package/dist/h-g-hexagon.d.ts +36 -0
- package/dist/h-g-hexagon.d.ts.map +1 -0
- package/dist/h-g-hexagon.js +38 -0
- package/dist/h-g-hexagon.js.map +1 -0
- package/dist/hex-grid.d.ts +149 -0
- package/dist/hex-grid.d.ts.map +1 -0
- package/dist/hex-grid.js +169 -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 +48 -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/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,208 @@
|
|
|
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
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether a Midgard coordinate range
|
|
3
|
+
* should be filled around its skeleton.
|
|
4
|
+
*/
|
|
5
|
+
export declare class CoordinateRangeFillAround {
|
|
6
|
+
/**
|
|
7
|
+
* Determines whether surrounding coordinates should be added.
|
|
8
|
+
*
|
|
9
|
+
* A 1 by 1 skeleton can choose whether to use fillAround.
|
|
10
|
+
* Any larger skeleton is always filled around automatically.
|
|
11
|
+
*
|
|
12
|
+
* @param width - The width of the coordinate range.
|
|
13
|
+
* @param height - The height of the coordinate range.
|
|
14
|
+
* @param fillAround - Whether a 1 by 1 range should be filled around.
|
|
15
|
+
* @returns True if the range should be filled around.
|
|
16
|
+
*/
|
|
17
|
+
shouldFillAround(width: number, height: number, fillAround?: boolean): boolean;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=c-r-fill-around.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c-r-fill-around.d.ts","sourceRoot":"","sources":["../src/c-r-fill-around.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,yBAAyB;IAClC;;;;;;;;;;OAUG;IACH,gBAAgB,CACd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,OAAe,GAC1B,OAAO,CAaT;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether a Midgard coordinate range
|
|
3
|
+
* should be filled around its skeleton.
|
|
4
|
+
*/
|
|
5
|
+
export class CoordinateRangeFillAround {
|
|
6
|
+
/**
|
|
7
|
+
* Determines whether surrounding coordinates should be added.
|
|
8
|
+
*
|
|
9
|
+
* A 1 by 1 skeleton can choose whether to use fillAround.
|
|
10
|
+
* Any larger skeleton is always filled around automatically.
|
|
11
|
+
*
|
|
12
|
+
* @param width - The width of the coordinate range.
|
|
13
|
+
* @param height - The height of the coordinate range.
|
|
14
|
+
* @param fillAround - Whether a 1 by 1 range should be filled around.
|
|
15
|
+
* @returns True if the range should be filled around.
|
|
16
|
+
*/
|
|
17
|
+
shouldFillAround(width, height, fillAround = false) {
|
|
18
|
+
const isSingleCoordinate = width === 1 && height === 1;
|
|
19
|
+
if (!isSingleCoordinate) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
if (fillAround) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=c-r-fill-around.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c-r-fill-around.js","sourceRoot":"","sources":["../src/c-r-fill-around.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,yBAAyB;IAClC;;;;;;;;;;OAUG;IACH,gBAAgB,CACd,KAAa,EACb,MAAc,EACd,UAAU,GAAY,KAAK;QAE3B,MAAM,kBAAkB,GACtB,KAAK,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,CAAA;QAE7B,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Coordinate } from './coordinate.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the skeleton coordinates for a Midgard coordinate range.
|
|
4
|
+
*
|
|
5
|
+
* The upper-left skeleton coordinate is always (2, 2).
|
|
6
|
+
* Skeleton coordinates use steps of two in both directions.
|
|
7
|
+
*/
|
|
8
|
+
export declare class CoordinateRangeSkeleton {
|
|
9
|
+
/**
|
|
10
|
+
* Creates a rectangular skeleton of coordinates.
|
|
11
|
+
*
|
|
12
|
+
* @param width - The number of skeleton coordinates horizontally.
|
|
13
|
+
* @param height - The number of skeleton coordinates vertically.
|
|
14
|
+
* @returns The coordinates that form the skeleton.
|
|
15
|
+
*/
|
|
16
|
+
create(width: number, height: number): Coordinate[];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=c-r-skeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c-r-skeleton.d.ts","sourceRoot":"","sources":["../src/c-r-skeleton.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;GAKG;AACH,qBAAa,uBAAuB;IAClC;;;;;;OAMG;IACH,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,UAAU,EAAE,CAoBd;CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates the skeleton coordinates for a Midgard coordinate range.
|
|
3
|
+
*
|
|
4
|
+
* The upper-left skeleton coordinate is always (2, 2).
|
|
5
|
+
* Skeleton coordinates use steps of two in both directions.
|
|
6
|
+
*/
|
|
7
|
+
export class CoordinateRangeSkeleton {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a rectangular skeleton of coordinates.
|
|
10
|
+
*
|
|
11
|
+
* @param width - The number of skeleton coordinates horizontally.
|
|
12
|
+
* @param height - The number of skeleton coordinates vertically.
|
|
13
|
+
* @returns The coordinates that form the skeleton.
|
|
14
|
+
*/
|
|
15
|
+
create(width, height) {
|
|
16
|
+
const coordinates = [];
|
|
17
|
+
const startX = 2;
|
|
18
|
+
const startY = 2;
|
|
19
|
+
for (let yIndex = 0; yIndex < height; yIndex++) {
|
|
20
|
+
const y = startY + yIndex * 2;
|
|
21
|
+
for (let xIndex = 0; xIndex < width; xIndex++) {
|
|
22
|
+
const x = startX + xIndex * 2;
|
|
23
|
+
coordinates.push({
|
|
24
|
+
x,
|
|
25
|
+
y
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return coordinates;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=c-r-skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c-r-skeleton.js","sourceRoot":"","sources":["../src/c-r-skeleton.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,uBAAuB;IAClC;;;;;;OAMG;IACH,MAAM,CACJ,KAAa,EACb,MAAc;QAEd,MAAM,WAAW,GAAiB,EAAE,CAAA;QAEpC,MAAM,MAAM,GAAG,CAAC,CAAA;QAChB,MAAM,MAAM,GAAG,CAAC,CAAA;QAEhB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAA;YAE7B,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;gBAC9C,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,CAAA;gBAE7B,WAAW,CAAC,IAAI,CAAC;oBACf,CAAC;oBACD,CAAC;iBACF,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAA;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates the dimensions of a Midgard coordinate range.
|
|
3
|
+
*/
|
|
4
|
+
export declare class CoordinateRangeValidator {
|
|
5
|
+
/**
|
|
6
|
+
* Checks whether width and height are valid range dimensions.
|
|
7
|
+
*
|
|
8
|
+
* Both dimensions must be positive integers.
|
|
9
|
+
*
|
|
10
|
+
* @param width - The width of the coordinate range.
|
|
11
|
+
* @param height - The height of the coordinate range.
|
|
12
|
+
* @returns True if both dimensions are valid.
|
|
13
|
+
*/
|
|
14
|
+
isValid(width: number, height: number): boolean;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=c-r-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c-r-validation.d.ts","sourceRoot":"","sources":["../src/c-r-validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,wBAAwB;IACjC;;;;;;;;OAQG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAkBT;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates the dimensions of a Midgard coordinate range.
|
|
3
|
+
*/
|
|
4
|
+
export class CoordinateRangeValidator {
|
|
5
|
+
/**
|
|
6
|
+
* Checks whether width and height are valid range dimensions.
|
|
7
|
+
*
|
|
8
|
+
* Both dimensions must be positive integers.
|
|
9
|
+
*
|
|
10
|
+
* @param width - The width of the coordinate range.
|
|
11
|
+
* @param height - The height of the coordinate range.
|
|
12
|
+
* @returns True if both dimensions are valid.
|
|
13
|
+
*/
|
|
14
|
+
isValid(width, height) {
|
|
15
|
+
if (!Number.isInteger(width)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (!Number.isInteger(height)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (width < 1) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (height < 1) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=c-r-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c-r-validation.js","sourceRoot":"","sources":["../src/c-r-validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,wBAAwB;IACjC;;;;;;;;OAQG;IACH,OAAO,CACL,KAAa,EACb,MAAc;QAEd,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Coordinate } from './coordinate.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents a Midgard coordinate with a z-index for rendering.
|
|
4
|
+
*
|
|
5
|
+
* The z-index is based on the coordinate's y row.
|
|
6
|
+
* The row with the lowest y value starts at 100,
|
|
7
|
+
* and each following row increases by 100.
|
|
8
|
+
*/
|
|
9
|
+
export type LayeredCoordinate = {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
zIndex: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Handles sorting and layering of Midgard coordinates
|
|
16
|
+
* for rendering.
|
|
17
|
+
*/
|
|
18
|
+
export declare class CoordinateLayer {
|
|
19
|
+
private readonly coordinates;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new coordinate layer.
|
|
22
|
+
*
|
|
23
|
+
* A copy of the coordinates is stored so that the original
|
|
24
|
+
* array is not changed.
|
|
25
|
+
*
|
|
26
|
+
* @param coordinates - The coordinates to sort and layer.
|
|
27
|
+
*/
|
|
28
|
+
constructor(coordinates: Coordinate[]);
|
|
29
|
+
/**
|
|
30
|
+
* Sorts the coordinates by y first and x second.
|
|
31
|
+
*
|
|
32
|
+
* Coordinates with the lowest y value come first.
|
|
33
|
+
* Coordinates on the same y row are ordered from
|
|
34
|
+
* the lowest x value to the highest x value.
|
|
35
|
+
*
|
|
36
|
+
* @returns A new array containing the sorted coordinates.
|
|
37
|
+
*/
|
|
38
|
+
sortCoordinates(): Coordinate[];
|
|
39
|
+
/**
|
|
40
|
+
* Creates layered coordinates for rendering a Midgard hex grid.
|
|
41
|
+
*
|
|
42
|
+
* Coordinates are ordered by y first and x second.
|
|
43
|
+
* The first y row receives z-index 100.
|
|
44
|
+
* Each following y row increases the z-index by 100.
|
|
45
|
+
*
|
|
46
|
+
* All coordinates on the same y row receive the same z-index.
|
|
47
|
+
*
|
|
48
|
+
* @returns Sorted coordinates with their calculated z-index.
|
|
49
|
+
*/
|
|
50
|
+
getLayeredCoordinates(): LayeredCoordinate[];
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=coordinate-layer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinate-layer.d.ts","sourceRoot":"","sources":["../src/coordinate-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAE1C;;;;;;;OAOG;IACH,YAAY,WAAW,EAAE,UAAU,EAAE,EAEpC;IAED;;;;;;;;OAQG;IACH,eAAe,IAAI,UAAU,EAAE,CAY9B;IAED;;;;;;;;;;OAUG;IACH,qBAAqB,IAAI,iBAAiB,EAAE,CAqB3C;CACF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles sorting and layering of Midgard coordinates
|
|
3
|
+
* for rendering.
|
|
4
|
+
*/
|
|
5
|
+
export class CoordinateLayer {
|
|
6
|
+
coordinates;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new coordinate layer.
|
|
9
|
+
*
|
|
10
|
+
* A copy of the coordinates is stored so that the original
|
|
11
|
+
* array is not changed.
|
|
12
|
+
*
|
|
13
|
+
* @param coordinates - The coordinates to sort and layer.
|
|
14
|
+
*/
|
|
15
|
+
constructor(coordinates) {
|
|
16
|
+
this.coordinates = [...coordinates];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Sorts the coordinates by y first and x second.
|
|
20
|
+
*
|
|
21
|
+
* Coordinates with the lowest y value come first.
|
|
22
|
+
* Coordinates on the same y row are ordered from
|
|
23
|
+
* the lowest x value to the highest x value.
|
|
24
|
+
*
|
|
25
|
+
* @returns A new array containing the sorted coordinates.
|
|
26
|
+
*/
|
|
27
|
+
sortCoordinates() {
|
|
28
|
+
const sortedCoordinates = [...this.coordinates];
|
|
29
|
+
sortedCoordinates.sort((firstCoordinate, secondCoordinate) => {
|
|
30
|
+
if (firstCoordinate.y !== secondCoordinate.y) {
|
|
31
|
+
return firstCoordinate.y - secondCoordinate.y;
|
|
32
|
+
}
|
|
33
|
+
return firstCoordinate.x - secondCoordinate.x;
|
|
34
|
+
});
|
|
35
|
+
return sortedCoordinates;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Creates layered coordinates for rendering a Midgard hex grid.
|
|
39
|
+
*
|
|
40
|
+
* Coordinates are ordered by y first and x second.
|
|
41
|
+
* The first y row receives z-index 100.
|
|
42
|
+
* Each following y row increases the z-index by 100.
|
|
43
|
+
*
|
|
44
|
+
* All coordinates on the same y row receive the same z-index.
|
|
45
|
+
*
|
|
46
|
+
* @returns Sorted coordinates with their calculated z-index.
|
|
47
|
+
*/
|
|
48
|
+
getLayeredCoordinates() {
|
|
49
|
+
const sortedCoordinates = this.sortCoordinates();
|
|
50
|
+
const layeredCoordinates = [];
|
|
51
|
+
let previousY;
|
|
52
|
+
let zIndex = 0;
|
|
53
|
+
for (const coordinate of sortedCoordinates) {
|
|
54
|
+
if (coordinate.y !== previousY) {
|
|
55
|
+
zIndex += 100;
|
|
56
|
+
previousY = coordinate.y;
|
|
57
|
+
}
|
|
58
|
+
layeredCoordinates.push({
|
|
59
|
+
x: coordinate.x,
|
|
60
|
+
y: coordinate.y,
|
|
61
|
+
zIndex
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return layeredCoordinates;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=coordinate-layer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinate-layer.js","sourceRoot":"","sources":["../src/coordinate-layer.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,MAAM,OAAO,eAAe;IACT,WAAW,CAAc;IAE1C;;;;;;;OAOG;IACH,YAAY,WAAyB;QACnC,IAAI,CAAC,WAAW,GAAG,CAAC,GAAG,WAAW,CAAC,CAAA;IACrC,CAAC;IAED;;;;;;;;OAQG;IACH,eAAe;QACb,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAA;QAE/C,iBAAiB,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,gBAAgB,EAAE,EAAE;YAC3D,IAAI,eAAe,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,EAAE,CAAC;gBAC7C,OAAO,eAAe,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAA;YAC/C,CAAC;YAED,OAAO,eAAe,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAA;QAC/C,CAAC,CAAC,CAAA;QAEF,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IAED;;;;;;;;;;OAUG;IACH,qBAAqB;QACnB,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;QAChD,MAAM,kBAAkB,GAAwB,EAAE,CAAA;QAElD,IAAI,SAA6B,CAAA;QACjC,IAAI,MAAM,GAAG,CAAC,CAAA;QAEd,KAAK,MAAM,UAAU,IAAI,iBAAiB,EAAE,CAAC;YAC3C,IAAI,UAAU,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,CAAA;gBACb,SAAS,GAAG,UAAU,CAAC,CAAC,CAAA;YAC1B,CAAC;YAED,kBAAkB,CAAC,IAAI,CAAC;gBACtB,CAAC,EAAE,UAAU,CAAC,CAAC;gBACf,CAAC,EAAE,UAAU,CAAC,CAAC;gBACf,MAAM;aACP,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,kBAAkB,CAAA;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Coordinate } from './coordinate.js';
|
|
2
|
+
import type { Point } from './geometry.js';
|
|
3
|
+
import type { GridOrientation } from './orientation.js';
|
|
4
|
+
/**
|
|
5
|
+
* Converts Midgard grid coordinates into geometric center positions.
|
|
6
|
+
*
|
|
7
|
+
* The calculated point represents the center of a hexagon
|
|
8
|
+
* in a two-dimensional coordinate system such as SVG.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CoordinatePositioner {
|
|
11
|
+
private readonly orientation;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new coordinate positioner.
|
|
14
|
+
*
|
|
15
|
+
* @param orientation - The orientation of the hex grid.
|
|
16
|
+
*/
|
|
17
|
+
constructor(orientation: GridOrientation);
|
|
18
|
+
/**
|
|
19
|
+
* Calculates the center position of a Midgard coordinate.
|
|
20
|
+
*
|
|
21
|
+
* For an x-dominated grid, dimension represents the
|
|
22
|
+
* complete width of one hexagon.
|
|
23
|
+
*
|
|
24
|
+
* For a y-dominated grid, dimension represents the
|
|
25
|
+
* complete height of one hexagon.
|
|
26
|
+
*
|
|
27
|
+
* @param coordinate - The Midgard coordinate to position.
|
|
28
|
+
* @param dimension - The width or height of one hexagon.
|
|
29
|
+
* @returns The calculated center point.
|
|
30
|
+
*/
|
|
31
|
+
getCenterPosition(coordinate: Coordinate, dimension: number): Point;
|
|
32
|
+
/**
|
|
33
|
+
* Calculates the center position in an x-dominated grid.
|
|
34
|
+
*
|
|
35
|
+
* @param coordinate - The Midgard coordinate to position.
|
|
36
|
+
* @param width - The complete width of one hexagon.
|
|
37
|
+
* @returns The calculated center point.
|
|
38
|
+
*/
|
|
39
|
+
getXDominatedCenterPosition(coordinate: Coordinate, width: number): Point;
|
|
40
|
+
/**
|
|
41
|
+
* Calculates the center position in a y-dominated grid.
|
|
42
|
+
*
|
|
43
|
+
* @param coordinate - The Midgard coordinate to position.
|
|
44
|
+
* @param height - The complete height of one hexagon.
|
|
45
|
+
* @returns The calculated center point.
|
|
46
|
+
*/
|
|
47
|
+
getYDominatedCenterPosition(coordinate: Coordinate, height: number): Point;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=coordinate-positioner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinate-positioner.d.ts","sourceRoot":"","sources":["../src/coordinate-positioner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEvD;;;;;GAKG;AACH,qBAAa,oBAAoB;IAE/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiB;IAE7C;;;;OAIG;IACH,YAAY,WAAW,EAAE,eAAe,EAIvC;IAED;;;;;;;;;;;;OAYG;IACI,iBAAiB,CACtB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,GAChB,KAAK,CAgBP;IAED;;;;;;OAMG;IACI,2BAA2B,CAChC,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,GACZ,KAAK,CAeP;IAED;;;;;;OAMG;IACI,2BAA2B,CAChC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,KAAK,CAeP;CAEF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts Midgard grid coordinates into geometric center positions.
|
|
3
|
+
*
|
|
4
|
+
* The calculated point represents the center of a hexagon
|
|
5
|
+
* in a two-dimensional coordinate system such as SVG.
|
|
6
|
+
*/
|
|
7
|
+
export class CoordinatePositioner {
|
|
8
|
+
orientation;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new coordinate positioner.
|
|
11
|
+
*
|
|
12
|
+
* @param orientation - The orientation of the hex grid.
|
|
13
|
+
*/
|
|
14
|
+
constructor(orientation) {
|
|
15
|
+
this.orientation = orientation;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Calculates the center position of a Midgard coordinate.
|
|
19
|
+
*
|
|
20
|
+
* For an x-dominated grid, dimension represents the
|
|
21
|
+
* complete width of one hexagon.
|
|
22
|
+
*
|
|
23
|
+
* For a y-dominated grid, dimension represents the
|
|
24
|
+
* complete height of one hexagon.
|
|
25
|
+
*
|
|
26
|
+
* @param coordinate - The Midgard coordinate to position.
|
|
27
|
+
* @param dimension - The width or height of one hexagon.
|
|
28
|
+
* @returns The calculated center point.
|
|
29
|
+
*/
|
|
30
|
+
getCenterPosition(coordinate, dimension) {
|
|
31
|
+
if (this.orientation === 'x-dominated') {
|
|
32
|
+
return this.getXDominatedCenterPosition(coordinate, dimension);
|
|
33
|
+
}
|
|
34
|
+
return this.getYDominatedCenterPosition(coordinate, dimension);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Calculates the center position in an x-dominated grid.
|
|
38
|
+
*
|
|
39
|
+
* @param coordinate - The Midgard coordinate to position.
|
|
40
|
+
* @param width - The complete width of one hexagon.
|
|
41
|
+
* @returns The calculated center point.
|
|
42
|
+
*/
|
|
43
|
+
getXDominatedCenterPosition(coordinate, width) {
|
|
44
|
+
const hexagonHeight = (width * 2) / Math.sqrt(3);
|
|
45
|
+
const xStep = width / 2;
|
|
46
|
+
const yStep = (hexagonHeight * 3) / 4;
|
|
47
|
+
return {
|
|
48
|
+
x: coordinate.x * xStep,
|
|
49
|
+
y: coordinate.y * yStep
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Calculates the center position in a y-dominated grid.
|
|
54
|
+
*
|
|
55
|
+
* @param coordinate - The Midgard coordinate to position.
|
|
56
|
+
* @param height - The complete height of one hexagon.
|
|
57
|
+
* @returns The calculated center point.
|
|
58
|
+
*/
|
|
59
|
+
getYDominatedCenterPosition(coordinate, height) {
|
|
60
|
+
const hexagonWidth = (height * 2) / Math.sqrt(3);
|
|
61
|
+
const xStep = (hexagonWidth * 3) / 4;
|
|
62
|
+
const yStep = height / 2;
|
|
63
|
+
return {
|
|
64
|
+
x: coordinate.x * xStep,
|
|
65
|
+
y: coordinate.y * yStep
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=coordinate-positioner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinate-positioner.js","sourceRoot":"","sources":["../src/coordinate-positioner.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAEd,WAAW,CAAiB;IAE7C;;;;OAIG;IACH,YAAY,WAA4B;QAEtC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;IAEhC,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,iBAAiB,CACtB,UAAsB,EACtB,SAAiB;QAGjB,IAAI,IAAI,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;YAEvC,OAAO,IAAI,CAAC,2BAA2B,CACrC,UAAU,EACV,SAAS,CACV,CAAA;QAEH,CAAC;QAED,OAAO,IAAI,CAAC,2BAA2B,CACrC,UAAU,EACV,SAAS,CACV,CAAA;IAEH,CAAC;IAED;;;;;;OAMG;IACI,2BAA2B,CAChC,UAAsB,EACtB,KAAa;QAGb,MAAM,aAAa,GACjB,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAE5B,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,CAAA;QAEvB,MAAM,KAAK,GACT,CAAC,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAEzB,OAAO;YACL,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK;YACvB,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK;SACxB,CAAA;IAEH,CAAC;IAED;;;;;;OAMG;IACI,2BAA2B,CAChC,UAAsB,EACtB,MAAc;QAGd,MAAM,YAAY,GAChB,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAE7B,MAAM,KAAK,GACT,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAExB,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,CAAA;QAExB,OAAO;YACL,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK;YACvB,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK;SACxB,CAAA;IAEH,CAAC;CAEF"}
|