We treat Cube and Axial systems separately. Cube coordinates are a plane in x,y,z space, where x+y+z = 0. Axial coordinates have two axes q,r that are 60° or 120° apart.
See http://www.redblobgames.com/grids/hexagons/implementation.html
Generic hex field definition
Direction ranges from 0 to 5 by sides of the hexagon, we use North, South, West, East definitions for simplicity
q : Hex -> Basics.Float
Get q coordinate for Hex as Float value
q IntCubeHex ( 2, 3, -5 ) == 2.0
intQ : Hex -> Basics.Int
Get q coordinate for Hex as Int value, its generally not recommended to use on FloatCubeHex
intQ IntCubeHex ( 2, 3, -5 ) == 2
r : Hex -> Basics.Float
Get r coordinate for Hex as Float value
r IntCubeHex ( 2, 3, -5 ) == 3.0
intR : Hex -> Basics.Int
Get r coordinate for Hex as Int value, its generally not recommended to use on FloatCubeHex
intR IntCubeHex ( 2, 3, -5 ) == 3
s : Hex -> Basics.Float
Get s coordinate for Hex as Float value
s IntCubeHex ( 2, 3, -5 ) == -5.0
intS : Hex -> Basics.Int
Get s coordinate for Hex as Int value, its generally not recommended to use on FloatCubeHex
intS IntCubeHex ( 2, 3, -5 ) == 3
intFactory : ( Basics.Int, Basics.Int ) -> Hex
Build Hex object from Int coordinates
intFactory ( 2, 3 )
|> eq (IntCubeHex ( 2, 3, -5 ))
floatFactory : ( Basics.Float, Basics.Float ) -> Hex
Build Hex object from Float coordinates
floatFactory ( 2.5, 3.5 )
|> eq (FloatCubeHex ( 2.5, 3.5, -6.0 ))
toIntHex : Hex -> Hex
Convert Hex to IntCubeHex coordinate systems
FloatCubeHex ( 2.5, 3.5, -6.0 )
|> toIntHex
|> eq (IntCubeHex ( 2, 4, -6 ))
toFloatHex : Hex -> Hex
Convert Hex to FloatCubeHex coordinate systems
IntCubeHex ( 2, 3, -5 )
|> toFloatHex
|> eq (FloatCubeHex ( 2.0, 3.0, -5.0 ))
eq : Hex -> Hex -> Basics.Bool
Compare two Hex definitions, support both axial and cubic coordinates.
Not a strict comparation, FloatCubeHex is converted to IntCubeHex.
IntCubeHex ( 2, 3, -5 )
|> eq (IntCubeHex ( 2, 3, -5 ))
AxialHex ( 2, 3 )
|> eq (AxialHex ( 2, 3 ))
noteq : Hex -> Hex -> Basics.Bool
Compare two Hex definitions, if they are not equal, inversion of eq
IntCubeHex ( 2, 3, -5 )
|> noteq (IntCubeHex ( 1, 1, -2 ))
AxialHex ( 2, 3 )
|> noteq (AxialHex ( 2, 1 ))
add : Hex -> Hex -> Hex
Since cube coordinates come from 3d cartesian coordinates, I automatically get things like addition, subtraction, multiplication, and division. For example, you can have Hex(2, 0, -2) that represents two steps northeast, and add that to location Hex(3, -5, 2) the obvious way: Hex(2 + 3, 0 + -5, -2 + -2). With other coordinate systems like offset coordinates, you can’t do that and get what you want. These operations are just what you’d implement with 3d cartesian vectors, but I am using q, r, s names in this class instead of x, y, z
IntCubeHex ( 2, 3, -5 )
|> add (IntCubeHex ( 1, 2, -3 ))
|> eq (IntCubeHex ( 3, 5, -8 ))
sub : Hex -> Hex -> Hex
Subtraction of Hexes, more info in sum
description
IntCubeHex ( 1, 2, -3 )
|> sub (IntCubeHex ( 2, 3, -5 ))
|> eq (IntCubeHex ( 1, 1, -2 ))
mul : Basics.Int -> Hex -> Hex
Multiplication of Hexes, more info in sum
description
IntCubeHex ( 2, 3, -5 )
|> mult 5
|> eq (IntCubeHex ( 10, 15, -25 ))
length : Hex -> Basics.Int
Length of Hex.
length (IntCubeHex ( 2, 3, -5 )) == 5
length (FloatCubeHex ( 2.2, 3.3, -5.5 )) == 5
distance : Hex -> Hex -> Basics.Int
The distance between two hexes is the length of the line between them.
distance (IntCubeHex ( 2, 3, -5 )) (FloatCubeHex ( 3.2, 4.3, -7.5 )) == 2
direction : Direction -> Hex
Direction relative to Hex polygon lines, we used shortcuts for the mix of North, East, South, West directions
neighbor : Hex -> Direction -> Hex
With distance, we defined two functions: length works on one argument and distance works with two. The same is true with neighbors. The direction function is with one argument and the neighbor function is with two.
neighbor (IntCubeHex ( 2, 3, -5 )) NW
|> eq (IntCubeHex ( 2, 4, -6 ))