# hexgrid

Tools for working with hex grid maps and coordinates.
Based in large part on the writings of [Amit Patel of Red Blob Games](https://www.redblobgames.com/grids/hexagons/).

## Usage

Install via your favorite package manager.

Each package supports CommonJS `require`, ESM `import`, and TypeScript usage.

You also have a choice: barrel imports or direct imports.

Barrel imports mean you're going to require/import everything from the same package-level namespace:

```typescript
// CommonJS
const { isPlainObject, isListOf } = require("@rickosborne/guard");
// ESM / TypeScript
import { isPlainObject, isListOf } from "@rickosborne/guard";
```

Implications:

- Nice and simple.
- Your build system needs to do tree-shaking well ... or you'll end up adding the entire package even if you only import two functions.

The other option is to use direct imports:

```typescript
// CommonJS
const { isPlainObject } = require("@rickosborne/guard/is-object");
const { isListOf } = require("@rickosborne/guard/is-list-of");
// ESM / TypeScript
import { isPlainObject } from "@rickosborne/guard/is-object.js";
import { isListOf } from "@rickosborne/guard/is-list-of.js";
```

Implications:

- You (probably) don't have to worry about tree-shaking as your build (likely) ends up with only the functions you need.

If you're using a modern build system, there aren't any strong reasons to prefer one way over the other.
It's really just down to your personal preference.

### A quick note about file extensions

Do you need to use file extensions?
And if so, which extensions?

Honestly ... this is a dumpster fire question.
It really comes down to your own setup and configuration.

Within each package itself:

- The CommonJS files all have `.cjs` extensions.
- The ESM files all have `.mjs` extensions.
- Node subpath exports have been set up to send `.js` imports to the `.cjs` (via `require`) or `.mjs` (via `import`) files, depending on your setup.

So, in theory, the only extension which _won't_ work would be `.ts` because the source isn't included.

If you run into a problem with a particular configuration, file a GitHub issue with:

- Your `tsconfig.json`'s `module`, `moduleResolution`, and `target` settings.
- Your `package.json`'s `type` and `imports` settings.
- An example of another package which imports correctly for you.

## License

This package is licensed as [CC-BY-NC-SA-4.0] unless otherwise noted.
That is, Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.

[CC-BY-NC-SA-4.0]: https://creativecommons.org/licenses/by-nc-sa/4.0/


***

## API

### Functions

#### axialAdd

<a id="api-axialadd"></a>

```typescript
axialAdd: (left: AxialPoint, right: AxialPoint) => AxialPoint
```

Add together two axial points to form a third.


#### axialFromCube

<a id="api-axialfromcube"></a>

```typescript
axialFromCube: (cube: HexCubePoint) => AxialPoint
```

Rebrand a Cube point to an Axial point.


#### axialFromDoubleHeight

<a id="api-axialfromdoubleheight"></a>

```typescript
axialFromDoubleHeight: (double: DoubleHeightPoint) => AxialPoint
```

#### axialFromDoubleWidth

<a id="api-axialfromdoublewidth"></a>

```typescript
axialFromDoubleWidth: (double: DoubleWidthPoint) => AxialPoint
```

#### axialFromOffset

<a id="api-axialfromoffset"></a>

```typescript
axialFromOffset: <S extends OffsetSystem>(offset: OffsetPoint<S>) => AxialPoint
```

#### axialFromQR

<a id="api-axialfromqr"></a>

```typescript
axialFromQR: (q: number, r: number) => AxialPoint
```

#### axialIntersection

<a id="api-axialintersection"></a>

```typescript
axialIntersection: (center1: AxialPoint, radius1: number, center2: AxialPoint, radius2?: number) => AxialPoint[]
```

#### axialLerp

<a id="api-axiallerp"></a>

```typescript
axialLerp: (left: AxialPoint, right: AxialPoint, fraction01: number) => AxialPoint
```

#### axialLineDraw

<a id="api-axiallinedraw"></a>

```typescript
axialLineDraw: (left: AxialPoint, right: AxialPoint) => AxialPoint[]
```

#### axialNeighbor

<a id="api-axialneighbor"></a>

```typescript
axialNeighbor: (axial: AxialPoint, direction: AxialDirection) => AxialPoint
```

#### axialRange

<a id="api-axialrange"></a>

```typescript
axialRange: (center: AxialPoint, radius: number) => AxialPoint[]
```

#### axialRound

<a id="api-axialround"></a>

```typescript
axialRound: (axial: AxialPoint) => AxialPoint
```

#### axialSubtract

<a id="api-axialsubtract"></a>

```typescript
axialSubtract: (left: AxialPoint, right: AxialPoint) => AxialPoint
```

Subtract one axial point from another.


#### bareQRS

<a id="api-bareqrs"></a>

```typescript
bareQRS: (q: number, r: number) => BareQRSPoint
```

#### bareQRSScale

<a id="api-bareqrsscale"></a>

```typescript
bareQRSScale: (point: BareQRSPoint, factor: number) => BareQRSPoint
```

#### bareQRSSubtract

<a id="api-bareqrssubtract"></a>

```typescript
bareQRSSubtract: (left: BareQRSPoint, right: BareQRSPoint) => BareQRSPoint
```

#### coverRect

<a id="api-coverrect"></a>

```typescript
coverRect: (width: number, height: number, layout: HexLayout) => QRWithXY[]
```

Generate a hex grid which completely covers a rectangle of the given dimensions.


#### cubeAdd

<a id="api-cubeadd"></a>

```typescript
cubeAdd: (left: HexCubePoint, right: HexCubePoint) => HexCubePoint
```

Add two Cube points together.


#### cubeDistance

<a id="api-cubedistance"></a>

```typescript
cubeDistance: (left: HexCubePoint, right: HexCubePoint) => number
```

Calculate the Manhattan distance between two points.


#### cubeFromAxial

<a id="api-cubefromaxial"></a>

```typescript
cubeFromAxial: (axial: AxialPoint) => HexCubePoint
```

Transform an Axial point into a Cube point by calculating and materializing `s`.


#### cubeFromDoubleHeight

<a id="api-cubefromdoubleheight"></a>

```typescript
cubeFromDoubleHeight: (double: DoubleHeightPoint) => HexCubePoint
```

#### cubeFromDoubleWidth

<a id="api-cubefromdoublewidth"></a>

```typescript
cubeFromDoubleWidth: (double: DoubleWidthPoint) => HexCubePoint
```

#### cubeFromQR

<a id="api-cubefromqr"></a>

```typescript
cubeFromQR: (q: number, r: number) => HexCubePoint
```

Build a branded Cube point from `q` and `r` coordinates.


#### cubeHeading

<a id="api-cubeheading"></a>

```typescript
cubeHeading: (from: HexCubePoint, toward: HexCubePoint) => HexCubeDirection | undefined
```

#### cubeIntersection

<a id="api-cubeintersection"></a>

```typescript
cubeIntersection: (center1: HexCubePoint, radius1: number, center2: HexCubePoint, radius2?: number) => HexCubePoint[]
```

#### cubeLerp

<a id="api-cubelerp"></a>

```typescript
cubeLerp: (a: HexCubePoint, b: HexCubePoint, frac: number) => HexCubePoint
```

#### cubeLineDraw

<a id="api-cubelinedraw"></a>

```typescript
cubeLineDraw: (a: HexCubePoint, b: HexCubePoint) => HexCubePoint[]
```

#### cubeNeighbor

<a id="api-cubeneighbor"></a>

```typescript
cubeNeighbor: (cube: HexCubePoint, direction: HexCubeDirection | CubeDiagDirection) => HexCubePoint
```

Find the neighbor of the given hex in the given direction.


#### cubeRange

<a id="api-cuberange"></a>

```typescript
cubeRange: (center: HexCubePoint, radius: number) => HexCubePoint[]
```

#### cubeRotate

<a id="api-cuberotate"></a>

```typescript
cubeRotate: (center: HexCubePoint, outer: HexCubePoint, rotation: HexRotation) => HexCubePoint
```

#### cubeRound

<a id="api-cuberound"></a>

```typescript
cubeRound: (cube: HexCubePoint) => HexCubePoint
```

#### cubeSubtract

<a id="api-cubesubtract"></a>

```typescript
cubeSubtract: (left: HexCubePoint, right: HexCubePoint) => HexCubePoint
```

#### doubleHeightAdd

<a id="api-doubleheightadd"></a>

```typescript
doubleHeightAdd: (left: DoubleHeightPoint, right: DoubleHeightPoint) => DoubleHeightPoint
```

#### doubleHeightDistance

<a id="api-doubleheightdistance"></a>

```typescript
doubleHeightDistance: (left: DoubleHeightPoint, right: DoubleHeightPoint) => number
```

#### doubleHeightFromQRS

<a id="api-doubleheightfromqrs"></a>

```typescript
doubleHeightFromQRS: (qrs: BareQRSPoint) => DoubleHeightPoint
```

#### doubleHeightNeighbor

<a id="api-doubleheightneighbor"></a>

```typescript
doubleHeightNeighbor: (double: DoubleHeightPoint, direction: DoubleHeightDirection) => DoubleHeightPoint
```

#### doubleWidthAdd

<a id="api-doublewidthadd"></a>

```typescript
doubleWidthAdd: (left: DoubleWidthPoint, right: DoubleWidthPoint) => DoubleWidthPoint
```

#### doubleWidthDistance

<a id="api-doublewidthdistance"></a>

```typescript
doubleWidthDistance: (left: DoubleWidthPoint, right: DoubleWidthPoint) => number
```

#### doubleWidthFromQRS

<a id="api-doublewidthfromqrs"></a>

```typescript
doubleWidthFromQRS: (qrs: BareQRSPoint) => DoubleWidthPoint
```

#### doubleWidthNeighbor

<a id="api-doublewidthneighbor"></a>

```typescript
doubleWidthNeighbor: (double: DoubleWidthPoint, direction: DoubleWidthDirection) => DoubleWidthPoint
```

#### evenQFromQRS

<a id="api-evenqfromqrs"></a>

```typescript
evenQFromQRS: (point: BareQRSPoint) => EvenQPoint
```

#### evenRFromQRS

<a id="api-evenrfromqrs"></a>

```typescript
evenRFromQRS: (point: BareQRSPoint) => EvenRPoint
```

#### flatQRSFromPixel

<a id="api-flatqrsfrompixel"></a>

```typescript
flatQRSFromPixel: <P extends QRSPoint<S>, S extends QRSSystem>({ x, y }: {
    x: number;
    y: number;
}, builder: QRSBuilder<P>, scale?: number) => P
```

#### hexContainsChecker

<a id="api-hexcontainschecker"></a>

```typescript
hexContainsChecker: (corners: PointXY[]) => (xy: PointXY) => boolean
```

Build a function which can check to see if the given pixel coordinates would be contained by the hex described by the corners. To be useful, cache this function, and then call it with pixel coordinates translated to the original hex's center.


#### hexCorners

<a id="api-hexcorners"></a>

```typescript
hexCorners: (qrs: BareQRSPoint, layout: HexLayout) => PointXY[]
```

#### hexCornersContainPoint

<a id="api-hexcornerscontainpoint"></a>

```typescript
hexCornersContainPoint: (corners: PointXY[], xy: PointXY) => boolean
```

#### hexDistance

<a id="api-hexdistance"></a>

```typescript
hexDistance: (left: BareQRSPoint, right: BareQRSPoint) => number
```

Calculate the Manhattan distance between two hex points.


#### hexesWithin

<a id="api-hexeswithin"></a>

```typescript
hexesWithin: (radius: number) => number
```

How many hexes are reachable from a starting hex given a Manhattan distance radius?


#### hexEuclidDistance

<a id="api-hexeucliddistance"></a>

```typescript
hexEuclidDistance: (left: BareQRSPoint, right: BareQRSPoint) => number
```

Euclidean distance between two hex points.



#### hexReachable

<a id="api-hexreachable"></a>

```typescript
hexReachable: <P extends Point, Id extends string | number>(start: P, steps: number, directions: Readonly<Readonly<P>[]>, adder: (left: P, right: P) => P, identity: (point: P) => Id, isBlocked: (point: P, id: Id) => boolean, onPoint?: ((point: P, distance: number, prior: P, direction: Readonly<P>) => void) | undefined) => HexReachable<P>[]
```

#### lerp

<a id="api-lerp"></a>

```typescript
lerp: (a: number, b: number, frac: number) => number
```

Linear interpolate from `a` to `b` with `frac` fractional progress (percent complete, in the range `[0,1]`).


#### oddQFromQRS

<a id="api-oddqfromqrs"></a>

```typescript
oddQFromQRS: (point: BareQRSPoint) => OddQPoint
```

#### oddRFromQRS

<a id="api-oddrfromqrs"></a>

```typescript
oddRFromQRS: (point: BareQRSPoint) => OddRPoint
```

#### offsetDistance

<a id="api-offsetdistance"></a>

```typescript
offsetDistance: (left: OffsetPoint<OffsetSystem>, right: OffsetPoint<OffsetSystem>) => number
```

#### offsetNeighbor

<a id="api-offsetneighbor"></a>

```typescript
offsetNeighbor: <S extends OffsetSystem>(offset: OffsetPoint<S>, direction: OffsetDirection) => OffsetPoint<S>
```

#### pixelFromFlatQRS

<a id="api-pixelfromflatqrs"></a>

```typescript
pixelFromFlatQRS: ({ q, r }: BareQRSPoint, scale?: number) => PointXY
```

#### pixelFromPointyQRS

<a id="api-pixelfrompointyqrs"></a>

```typescript
pixelFromPointyQRS: ({ q, r }: BareQRSPoint, scale?: number) => PointXY
```

#### pixelFromQRS

<a id="api-pixelfromqrs"></a>

```typescript
pixelFromQRS: ({ q, r }: BareQRSPoint, { orientation: { f0, f1, f2, f3 }, origin: { x: cx, y: cy }, size: { x: scaleX, y: scaleY } }: HexLayout) => PointXY
```

#### pixelOffsetOfCorner

<a id="api-pixeloffsetofcorner"></a>

```typescript
pixelOffsetOfCorner: (t: HexCorner, u: HexLayout) => Readonly<PointXY>
```

#### pointyQRSFromPixel

<a id="api-pointyqrsfrompixel"></a>

```typescript
pointyQRSFromPixel: <P extends QRSPoint<S>, S extends QRSSystem>({ x, y }: {
    x: number;
    y: number;
}, builder: QRSBuilder<P>, scale?: number) => P
```

#### qrsEQ

<a id="api-qrseq"></a>

```typescript
qrsEQ: (a: Readonly<BareHexCubePoint>, b: Readonly<BareHexCubePoint>) => boolean
```

#### qrsFromDoubleHeight

<a id="api-qrsfromdoubleheight"></a>

```typescript
qrsFromDoubleHeight: <S extends QRSSystem, P extends QRSPoint<S>>(double: DoubleHeightPoint, builder: QRSBuilder<P>) => P
```

#### qrsFromDoubleWidth

<a id="api-qrsfromdoublewidth"></a>

```typescript
qrsFromDoubleWidth: <S extends QRSSystem, P extends QRSPoint<S>>(double: DoubleWidthPoint, builder: QRSBuilder<P>) => P
```

#### qrsFromPixel

<a id="api-qrsfrompixel"></a>

```typescript
qrsFromPixel: <P extends QRSPoint<S>, S extends QRSSystem>({ x, y }: PointXY, { orientation: { b0, b1, b2, b3 }, origin: { x: cx, y: cy }, size: { x: scaleX, y: scaleY } }: HexLayout, builder: QRSBuilder<P>) => P
```

#### qrsHashCode

<a id="api-qrshashcode"></a>

```typescript
qrsHashCode: ({ q, r }: BareQRSPoint) => bigint
```

Generate a (very simplistic) hash code for a hex point which could be used as a Map/Hash key.


#### qrsIntersection

<a id="api-qrsintersection"></a>

```typescript
qrsIntersection: <P extends QRSPoint<QRSSystem>>(buildFn: QRSBuilder<P>, center1: P, radius1: number, center2: P, radius2?: number) => P[]
```

#### qrsRange

<a id="api-qrsrange"></a>

```typescript
qrsRange: <P extends QRSPoint<QRSSystem>>(addFn: QRSAdder<P>, buildFn: QRSBuilder<P>, center: P, radius: number) => P[]
```

Calculate all the points within a given radius of a given center.


#### qrsRing

<a id="api-qrsring"></a>

```typescript
qrsRing: <P extends QRSPoint<S>, S extends QRSSystem>(center: P, radius: number, builder: QRSBuilder<P>) => P[]
```

#### qrsScale

<a id="api-qrsscale"></a>

```typescript
qrsScale: <P extends QRSPoint<S>, S extends QRSSystem>(point: P, factor: number, builder: QRSBuilder<P>) => P
```

#### qrsSpiral

<a id="api-qrsspiral"></a>

```typescript
qrsSpiral: <P extends QRSPoint<S>, S extends QRSSystem>(center: P, radius: number, builder: QRSBuilder<P>) => P[]
```

#### qrsSubtract

<a id="api-qrssubtract"></a>

```typescript
qrsSubtract: <P extends QRSPoint<S>, S extends QRSSystem>(left: P, right: P, builder: QRSBuilder<P>) => P
```

#### stringifyAxial

<a id="api-stringifyaxial"></a>

```typescript
stringifyAxial: ({ q, r }: AxialPoint | BareQRSPoint) => string
```

#### stringifyCube

<a id="api-stringifycube"></a>

```typescript
stringifyCube: ({ q, r, s }: BareHexCubePoint) => string
```

#### stringifyOffset

<a id="api-stringifyoffset"></a>

```typescript
stringifyOffset: ({ row, col, system }: OffsetPoint<OffsetSystem>) => string
```

#### svgForHexGrid

<a id="api-svgforhexgrid"></a>

```typescript
svgForHexGrid: (grid: {
    height: number;
    hexes: QRWithXY[];
    width: number;
}, layout: HexLayout) => string
```

Build a rudimentary SVG for the described grid. Intended more for testing and visual inspection than for anything significant.


#### triangleContainsChecker

<a id="api-trianglecontainschecker"></a>

```typescript
triangleContainsChecker: (triangle: [PointXY, PointXY, PointXY]) => (xy: PointXY) => boolean
```

Generate a function which can check to see if a given point is inside the triangle described by the three points.


#### triangleContainsPoint

<a id="api-trianglecontainspoint"></a>

```typescript
triangleContainsPoint: (triangle: [PointXY, PointXY, PointXY], point: PointXY) => boolean
```

### Interfaces

#### BareDouble

<a id="api-baredouble"></a>

```typescript
export interface BareDouble 
```

#### BareHexCubePoint

<a id="api-barehexcubepoint"></a>

```typescript
export interface BareHexCubePoint extends BareQRSPoint 
```

Cube points store the `s` value explicitly, instead of calculating it.


#### BareOffset

<a id="api-bareoffset"></a>

```typescript
export interface BareOffset 
```

#### BareQRSPoint

<a id="api-bareqrspoint"></a>

```typescript
export interface BareQRSPoint 
```

In the QRS notation, `q` is the column, while `r` is the row.


#### DoubleHeightPoint

<a id="api-doubleheightpoint"></a>

```typescript
export interface DoubleHeightPoint extends DoublePoint<DoubleHeight> 
```

#### DoublePoint

<a id="api-doublepoint"></a>

```typescript
export interface DoublePoint<SystemT extends DoubleSystem> extends Point, BareDouble 
```

#### DoubleWidthPoint

<a id="api-doublewidthpoint"></a>

```typescript
export interface DoubleWidthPoint extends DoublePoint<DoubleWidth> 
```

#### EvenQPoint

<a id="api-evenqpoint"></a>

```typescript
export interface EvenQPoint extends OffsetPoint<typeof EVEN_Q> 
```

#### EvenRPoint

<a id="api-evenrpoint"></a>

```typescript
export interface EvenRPoint extends OffsetPoint<typeof EVEN_R> 
```

#### HexCubePoint

<a id="api-hexcubepoint"></a>

```typescript
export interface HexCubePoint extends QRSPoint<Cube>, BareHexCubePoint 
```

#### HexLayout

<a id="api-hexlayout"></a>

```typescript
export interface HexLayout 
```

#### HexOrientation

<a id="api-hexorientation"></a>

```typescript
export interface HexOrientation 
```

#### HexOrientations

<a id="api-hexorientations"></a>

```typescript
export interface HexOrientations 
```

#### HexSystems

<a id="api-hexsystems"></a>

```typescript
export interface HexSystems 
```

#### OddQPoint

<a id="api-oddqpoint"></a>

```typescript
export interface OddQPoint extends OffsetPoint<typeof ODD_Q> 
```

#### OddRPoint

<a id="api-oddrpoint"></a>

```typescript
export interface OddRPoint extends OffsetPoint<typeof ODD_R> 
```

#### OffsetPoint

<a id="api-offsetpoint"></a>

```typescript
export interface OffsetPoint<SystemT extends OffsetSystem> extends Point, BareOffset 
```

#### Point

<a id="api-point"></a>

```typescript
export interface Point 
```

#### PointXY

<a id="api-pointxy"></a>

```typescript
export interface PointXY 
```

#### QRSPoint

<a id="api-qrspoint"></a>

```typescript
export interface QRSPoint<S extends QRSSystem> extends Point, BareQRSPoint 
```

A QRS Point which also has its [HexSystem](#api-hexsystem) materialized with its coordinates.


#### QRWithXY

<a id="api-qrwithxy"></a>

```typescript
export interface QRWithXY extends PointXY, BareQRSPoint 
```

### TypeAliases

#### Axial

<a id="api-axial"></a>

```typescript
type Axial = typeof AXIAL;
```

#### AxialDirection

<a id="api-axialdirection"></a>

```typescript
type AxialDirection = typeof AXIAL_POINTY_E | typeof AXIAL_POINTY_NE | typeof AXIAL_POINTY_NW | typeof AXIAL_POINTY_W | typeof AXIAL_POINTY_SW | typeof AXIAL_POINTY_SE;
```

#### AxialPoint

<a id="api-axialpoint"></a>

```typescript
type AxialPoint = QRSPoint<Axial>;
```

Axial coordinates don't store the `s` coordinate, as it can always be calculated via `q + r + s = 0`.


#### AxialTuple

<a id="api-axialtuple"></a>

```typescript
type AxialTuple = [q: number, r: number];
```

#### Axis

<a id="api-axis"></a>

```typescript
type Axis<P extends Point> = Exclude<keyof P, keyof Point>;
```

#### Cube

<a id="api-cube"></a>

```typescript
type Cube = typeof CUBE;
```

#### CubeDiagDirection

<a id="api-cubediagdirection"></a>

```typescript
type CubeDiagDirection = typeof CUBE_DIAG_SE | typeof CUBE_DIAG_NW | typeof CUBE_DIAG_POINTY_N | typeof CUBE_DIAG_POINTY_NE | typeof CUBE_DIAG_POINTY_S | typeof CUBE_DIAG_POINTY_SW;
```

#### CubeTuple

<a id="api-cubetuple"></a>

```typescript
type CubeTuple = [q: number, r: number, s: number];
```

#### DoubleHeight

<a id="api-doubleheight"></a>

```typescript
type DoubleHeight = typeof DOUBLE_H;
```

#### DoubleHeightDirection

<a id="api-doubleheightdirection"></a>

```typescript
type DoubleHeightDirection = typeof DOUBLE_H_N | typeof DOUBLE_H_NE | typeof DOUBLE_H_SE | typeof DOUBLE_H_S | typeof DOUBLE_H_SW | typeof DOUBLE_H_NW;
```

#### DoubleSystem

<a id="api-doublesystem"></a>

```typescript
type DoubleSystem = DoubleWidth | DoubleHeight;
```

#### DoubleWidth

<a id="api-doublewidth"></a>

```typescript
type DoubleWidth = typeof DOUBLE_W;
```

#### DoubleWidthDirection

<a id="api-doublewidthdirection"></a>

```typescript
type DoubleWidthDirection = typeof DOUBLE_W_E | typeof DOUBLE_W_SE | typeof DOUBLE_W_SW | typeof DOUBLE_W_W | typeof DOUBLE_W_NW | typeof DOUBLE_W_NE;
```

#### EvenQ

<a id="api-evenq"></a>

```typescript
type EvenQ = typeof EVEN_Q;
```

#### EvenR

<a id="api-evenr"></a>

```typescript
type EvenR = typeof EVEN_R;
```

#### HexCorner

<a id="api-hexcorner"></a>

```typescript
type HexCorner = 0 | 1 | 2 | 3 | 4 | 5;
```

#### HexCubeDirection

<a id="api-hexcubedirection"></a>

```typescript
type HexCubeDirection = typeof CUBE_POINTY_E | typeof CUBE_NE | typeof CUBE_POINTY_NW | typeof CUBE_POINTY_W | typeof CUBE_SW | typeof CUBE_POINTY_SE;
```

#### HexOrientationName

<a id="api-hexorientationname"></a>

```typescript
type HexOrientationName = keyof HexOrientations;
```

#### HexReachable

<a id="api-hexreachable"></a>

```typescript
type HexReachable<P extends Point> = {
    direction?: undefined;
    distance: 0;
    point: P;
    prior?: undefined;
} | {
    direction: Readonly<P>;
    distance: Exclude<number, 0>;
    point: P;
    prior: P;
};
```

#### HexRotation

<a id="api-hexrotation"></a>

```typescript
type HexRotation = 0 | typeof CW_60 | typeof CW_120 | typeof CW_180 | typeof CW_240 | typeof CW_300;
```

#### HexSystem

<a id="api-hexsystem"></a>

```typescript
type HexSystem = keyof HexSystems;
```

#### OddQ

<a id="api-oddq"></a>

```typescript
type OddQ = typeof ODD_Q;
```

#### OddR

<a id="api-oddr"></a>

```typescript
type OddR = typeof ODD_R;
```

#### OffsetDirection

<a id="api-offsetdirection"></a>

```typescript
type OffsetDirection = typeof OFFSET_R_E | typeof OFFSET_R_NE | typeof OFFSET_R_NW | typeof OFFSET_R_W | typeof OFFSET_R_SW | typeof OFFSET_R_SE;
```

#### OffsetSystem

<a id="api-offsetsystem"></a>

```typescript
type OffsetSystem = typeof ODD_Q | typeof ODD_R | typeof EVEN_Q | typeof EVEN_R;
```

#### QRSAdder

<a id="api-qrsadder"></a>

```typescript
type QRSAdder<P extends QRSPoint<QRSSystem>> = (left: P, right: P) => P;
```

A function which can add together two QRS points with the same system.


#### QRSBuilder

<a id="api-qrsbuilder"></a>

```typescript
type QRSBuilder<P extends QRSPoint<QRSSystem>> = (q: number, r: number) => P;
```

A function which can structures numbers into a QRS point for a given system.


#### QRSSystem

<a id="api-qrssystem"></a>

```typescript
type QRSSystem = Axial | Cube;
```

### Variables

#### AXIAL

<a id="api-axial"></a>

```typescript
AXIAL: "axial"
```

#### AXIAL_DIRECTIONS

<a id="api-axial-directions"></a>

```typescript
AXIAL_DIRECTIONS: Readonly<AxialDirection[]>
```

#### AXIAL_EPSILON

<a id="api-axial-epsilon"></a>

```typescript
AXIAL_EPSILON: Readonly<{
    readonly q: 0.000001;
    readonly r: 0.000001;
    readonly system: "axial";
}>
```

#### AXIAL_FLAT_N

<a id="api-axial-flat-n"></a>

```typescript
AXIAL_FLAT_N: Readonly<{
    readonly q: 0;
    readonly r: -1;
    readonly system: "axial";
}>
```

#### AXIAL_FLAT_NE

<a id="api-axial-flat-ne"></a>

```typescript
AXIAL_FLAT_NE: Readonly<{
    readonly q: 1;
    readonly r: -1;
    readonly system: "axial";
}>
```

#### AXIAL_FLAT_NW

<a id="api-axial-flat-nw"></a>

```typescript
AXIAL_FLAT_NW: Readonly<{
    readonly q: -1;
    readonly r: 0;
    readonly system: "axial";
}>
```

#### AXIAL_FLAT_S

<a id="api-axial-flat-s"></a>

```typescript
AXIAL_FLAT_S: Readonly<{
    readonly q: 0;
    readonly r: 1;
    readonly system: "axial";
}>
```

#### AXIAL_FLAT_SE

<a id="api-axial-flat-se"></a>

```typescript
AXIAL_FLAT_SE: Readonly<{
    readonly q: 1;
    readonly r: 0;
    readonly system: "axial";
}>
```

#### AXIAL_FLAT_SW

<a id="api-axial-flat-sw"></a>

```typescript
AXIAL_FLAT_SW: Readonly<{
    readonly q: -1;
    readonly r: 1;
    readonly system: "axial";
}>
```

#### AXIAL_ORIGIN

<a id="api-axial-origin"></a>

```typescript
AXIAL_ORIGIN: Readonly<{
    readonly q: 0;
    readonly r: 0;
    readonly system: "axial";
}>
```

#### AXIAL_POINTY_E

<a id="api-axial-pointy-e"></a>

```typescript
AXIAL_POINTY_E: Readonly<{
    readonly q: 1;
    readonly r: 0;
    readonly system: "axial";
}>
```

#### AXIAL_POINTY_NE

<a id="api-axial-pointy-ne"></a>

```typescript
AXIAL_POINTY_NE: Readonly<{
    readonly q: 1;
    readonly r: -1;
    readonly system: "axial";
}>
```

#### AXIAL_POINTY_NW

<a id="api-axial-pointy-nw"></a>

```typescript
AXIAL_POINTY_NW: Readonly<{
    readonly q: 0;
    readonly r: -1;
    readonly system: "axial";
}>
```

#### AXIAL_POINTY_SE

<a id="api-axial-pointy-se"></a>

```typescript
AXIAL_POINTY_SE: Readonly<{
    readonly q: 0;
    readonly r: 1;
    readonly system: "axial";
}>
```

#### AXIAL_POINTY_SW

<a id="api-axial-pointy-sw"></a>

```typescript
AXIAL_POINTY_SW: Readonly<{
    readonly q: -1;
    readonly r: 1;
    readonly system: "axial";
}>
```

#### AXIAL_POINTY_W

<a id="api-axial-pointy-w"></a>

```typescript
AXIAL_POINTY_W: Readonly<{
    readonly q: -1;
    readonly r: 0;
    readonly system: "axial";
}>
```

#### CCW_120

<a id="api-ccw-120"></a>

```typescript
CCW_120 = 240
```

#### CCW_180

<a id="api-ccw-180"></a>

```typescript
CCW_180 = 180
```

#### CCW_240

<a id="api-ccw-240"></a>

```typescript
CCW_240 = 120
```

#### CCW_300

<a id="api-ccw-300"></a>

```typescript
CCW_300 = 60
```

#### CCW_60

<a id="api-ccw-60"></a>

```typescript
CCW_60 = 300
```

#### CUBE

<a id="api-cube"></a>

```typescript
CUBE: "cube"
```

#### CUBE_DIAG_FLAT_E

<a id="api-cube-diag-flat-e"></a>

```typescript
CUBE_DIAG_FLAT_E: Readonly<{
    readonly q: 2;
    readonly r: -1;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_FLAT_NE

<a id="api-cube-diag-flat-ne"></a>

```typescript
CUBE_DIAG_FLAT_NE: Readonly<{
    readonly q: 1;
    readonly r: -2;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_FLAT_SW

<a id="api-cube-diag-flat-sw"></a>

```typescript
CUBE_DIAG_FLAT_SW: Readonly<{
    readonly q: -1;
    readonly r: 2;
    readonly s: -1;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_FLAT_W

<a id="api-cube-diag-flat-w"></a>

```typescript
CUBE_DIAG_FLAT_W: Readonly<{
    readonly q: -2;
    readonly r: 1;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_NW

<a id="api-cube-diag-nw"></a>

```typescript
CUBE_DIAG_NW: Readonly<{
    readonly q: -1;
    readonly r: -1;
    readonly s: 2;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_POINTY_N

<a id="api-cube-diag-pointy-n"></a>

```typescript
CUBE_DIAG_POINTY_N: Readonly<{
    readonly q: 1;
    readonly r: -2;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_POINTY_NE

<a id="api-cube-diag-pointy-ne"></a>

```typescript
CUBE_DIAG_POINTY_NE: Readonly<{
    readonly q: 2;
    readonly r: -1;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_POINTY_S

<a id="api-cube-diag-pointy-s"></a>

```typescript
CUBE_DIAG_POINTY_S: Readonly<{
    readonly q: -1;
    readonly r: 2;
    readonly s: -1;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_POINTY_SW

<a id="api-cube-diag-pointy-sw"></a>

```typescript
CUBE_DIAG_POINTY_SW: Readonly<{
    readonly q: -2;
    readonly r: 1;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_DIAG_SE

<a id="api-cube-diag-se"></a>

```typescript
CUBE_DIAG_SE: Readonly<{
    readonly q: 1;
    readonly r: 1;
    readonly s: -2;
    readonly system: "cube";
}>
```

#### CUBE_EPSILON

<a id="api-cube-epsilon"></a>

```typescript
CUBE_EPSILON: Readonly<{
    q: number;
    r: number;
    s: number;
    system: "cube";
}>
```

#### CUBE_FLAT_N

<a id="api-cube-flat-n"></a>

```typescript
CUBE_FLAT_N: Readonly<{
    readonly q: 0;
    readonly r: -1;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_FLAT_NW

<a id="api-cube-flat-nw"></a>

```typescript
CUBE_FLAT_NW: Readonly<{
    readonly q: -1;
    readonly r: 0;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_FLAT_S

<a id="api-cube-flat-s"></a>

```typescript
CUBE_FLAT_S: Readonly<{
    readonly q: 0;
    readonly r: 1;
    readonly s: -1;
    readonly system: "cube";
}>
```

#### CUBE_FLAT_SE

<a id="api-cube-flat-se"></a>

```typescript
CUBE_FLAT_SE: Readonly<{
    readonly q: 1;
    readonly r: 0;
    readonly s: -1;
    readonly system: "cube";
}>
```

#### CUBE_NE

<a id="api-cube-ne"></a>

```typescript
CUBE_NE: Readonly<{
    readonly q: 1;
    readonly r: -1;
    readonly s: 0;
    readonly system: "cube";
}>
```

#### CUBE_ORIGIN

<a id="api-cube-origin"></a>

```typescript
CUBE_ORIGIN: Readonly<{
    readonly q: 0;
    readonly r: 0;
    readonly s: 0;
    readonly system: "cube";
}>
```

#### CUBE_POINTY_E

<a id="api-cube-pointy-e"></a>

```typescript
CUBE_POINTY_E: Readonly<{
    readonly q: 1;
    readonly r: 0;
    readonly s: -1;
    readonly system: "cube";
}>
```

#### CUBE_POINTY_NW

<a id="api-cube-pointy-nw"></a>

```typescript
CUBE_POINTY_NW: Readonly<{
    readonly q: 0;
    readonly r: -1;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_POINTY_SE

<a id="api-cube-pointy-se"></a>

```typescript
CUBE_POINTY_SE: Readonly<{
    readonly q: 0;
    readonly r: 1;
    readonly s: -1;
    readonly system: "cube";
}>
```

#### CUBE_POINTY_W

<a id="api-cube-pointy-w"></a>

```typescript
CUBE_POINTY_W: Readonly<{
    readonly q: -1;
    readonly r: 0;
    readonly s: 1;
    readonly system: "cube";
}>
```

#### CUBE_SW

<a id="api-cube-sw"></a>

```typescript
CUBE_SW: Readonly<{
    readonly q: -1;
    readonly r: 1;
    readonly s: 0;
    readonly system: "cube";
}>
```

#### CW_120

<a id="api-cw-120"></a>

```typescript
CW_120 = 120
```

#### CW_180

<a id="api-cw-180"></a>

```typescript
CW_180 = 180
```

#### CW_240

<a id="api-cw-240"></a>

```typescript
CW_240 = 240
```

#### CW_300

<a id="api-cw-300"></a>

```typescript
CW_300 = 300
```

#### CW_60

<a id="api-cw-60"></a>

```typescript
CW_60 = 60
```

#### DOUBLE_H

<a id="api-double-h"></a>

```typescript
DOUBLE_H: "doubleH"
```

#### DOUBLE_H_N

<a id="api-double-h-n"></a>

```typescript
DOUBLE_H_N: Readonly<{
    readonly col: 0;
    readonly row: -2;
    readonly system: "doubleH";
}>
```

#### DOUBLE_H_NE

<a id="api-double-h-ne"></a>

```typescript
DOUBLE_H_NE: Readonly<{
    readonly col: 1;
    readonly row: -1;
    readonly system: "doubleH";
}>
```

#### DOUBLE_H_NW

<a id="api-double-h-nw"></a>

```typescript
DOUBLE_H_NW: Readonly<{
    readonly col: -1;
    readonly row: -1;
    readonly system: "doubleH";
}>
```

#### DOUBLE_H_S

<a id="api-double-h-s"></a>

```typescript
DOUBLE_H_S: Readonly<{
    readonly col: 0;
    readonly row: 2;
    readonly system: "doubleH";
}>
```

#### DOUBLE_H_SE

<a id="api-double-h-se"></a>

```typescript
DOUBLE_H_SE: Readonly<{
    readonly col: 1;
    readonly row: 1;
    readonly system: "doubleH";
}>
```

#### DOUBLE_H_SW

<a id="api-double-h-sw"></a>

```typescript
DOUBLE_H_SW: Readonly<{
    readonly col: -1;
    readonly row: 1;
    readonly system: "doubleH";
}>
```

#### DOUBLE_W

<a id="api-double-w"></a>

```typescript
DOUBLE_W: "doubleW"
```

#### DOUBLE_W_E

<a id="api-double-w-e"></a>

```typescript
DOUBLE_W_E: Readonly<{
    readonly col: 2;
    readonly row: 0;
    readonly system: "doubleW";
}>
```

#### DOUBLE_W_NE

<a id="api-double-w-ne"></a>

```typescript
DOUBLE_W_NE: Readonly<{
    readonly col: 1;
    readonly row: -1;
    readonly system: "doubleW";
}>
```

#### DOUBLE_W_NW

<a id="api-double-w-nw"></a>

```typescript
DOUBLE_W_NW: Readonly<{
    readonly col: -1;
    readonly row: 1;
    readonly system: "doubleW";
}>
```

#### DOUBLE_W_SE

<a id="api-double-w-se"></a>

```typescript
DOUBLE_W_SE: Readonly<{
    readonly col: 1;
    readonly row: 1;
    readonly system: "doubleW";
}>
```

#### DOUBLE_W_SW

<a id="api-double-w-sw"></a>

```typescript
DOUBLE_W_SW: Readonly<{
    readonly col: -1;
    readonly row: 1;
    readonly system: "doubleW";
}>
```

#### DOUBLE_W_W

<a id="api-double-w-w"></a>

```typescript
DOUBLE_W_W: Readonly<{
    readonly col: -2;
    readonly row: 0;
    readonly system: "doubleW";
}>
```

#### EVEN_Q

<a id="api-even-q"></a>

```typescript
EVEN_Q: "evenQ"
```

#### EVEN_R

<a id="api-even-r"></a>

```typescript
EVEN_R: "evenR"
```

#### FLAT

<a id="api-flat"></a>

```typescript
FLAT = "flat"
```

#### HEX_CORNERS

<a id="api-hex-corners"></a>

```typescript
HEX_CORNERS: readonly HexCorner[]
```

#### HEX_CUBE_DIRECTIONS

<a id="api-hex-cube-directions"></a>

```typescript
HEX_CUBE_DIRECTIONS: Readonly<HexCubeDirection[]>
```

#### HEX_SYSTEMS

<a id="api-hex-systems"></a>

```typescript
HEX_SYSTEMS: readonly HexSystem[]
```

#### ODD_Q

<a id="api-odd-q"></a>

```typescript
ODD_Q: "oddQ"
```

#### ODD_R

<a id="api-odd-r"></a>

```typescript
ODD_R: "oddR"
```

#### OFFSET_DIRECTIONS

<a id="api-offset-directions"></a>

```typescript
OFFSET_DIRECTIONS: Readonly<Readonly<OffsetDirection>[]>
```

#### OFFSET_Q_N

<a id="api-offset-q-n"></a>

```typescript
OFFSET_Q_N = 2
```

#### OFFSET_Q_NE

<a id="api-offset-q-ne"></a>

```typescript
OFFSET_Q_NE = 1
```

#### OFFSET_Q_NW

<a id="api-offset-q-nw"></a>

```typescript
OFFSET_Q_NW = 3
```

#### OFFSET_Q_S

<a id="api-offset-q-s"></a>

```typescript
OFFSET_Q_S = 5
```

#### OFFSET_Q_SE

<a id="api-offset-q-se"></a>

```typescript
OFFSET_Q_SE = 0
```

#### OFFSET_Q_SW

<a id="api-offset-q-sw"></a>

```typescript
OFFSET_Q_SW = 4
```

#### OFFSET_R_E

<a id="api-offset-r-e"></a>

```typescript
OFFSET_R_E = 0
```

#### OFFSET_R_NE

<a id="api-offset-r-ne"></a>

```typescript
OFFSET_R_NE = 1
```

#### OFFSET_R_NW

<a id="api-offset-r-nw"></a>

```typescript
OFFSET_R_NW = 2
```

#### OFFSET_R_SE

<a id="api-offset-r-se"></a>

```typescript
OFFSET_R_SE = 5
```

#### OFFSET_R_SW

<a id="api-offset-r-sw"></a>

```typescript
OFFSET_R_SW = 4
```

#### OFFSET_R_W

<a id="api-offset-r-w"></a>

```typescript
OFFSET_R_W = 3
```

#### ORIENTATION_FLAT

<a id="api-orientation-flat"></a>

```typescript
ORIENTATION_FLAT: Readonly<HexOrientation>
```

#### ORIENTATION_POINTY

<a id="api-orientation-pointy"></a>

```typescript
ORIENTATION_POINTY: Readonly<HexOrientation>
```

#### POINTY

<a id="api-pointy"></a>

```typescript
POINTY = "pointy"
```

#### QRS_ORIGIN

<a id="api-qrs-origin"></a>

```typescript
QRS_ORIGIN: Readonly<{
    readonly q: 0;
    readonly r: 0;
}>
```

#### SQRT_3

<a id="api-sqrt-3"></a>

```typescript
SQRT_3: number
```

#### SQRT_3_2

<a id="api-sqrt-3-2"></a>

```typescript
SQRT_3_2: number
```

#### SQRT_3_3

<a id="api-sqrt-3-3"></a>

```typescript
SQRT_3_3: number
```

#### TWO_PI

<a id="api-two-pi"></a>

```typescript
TWO_PI: number
```

