-
Notifications
You must be signed in to change notification settings - Fork 30
Coordinate Systems HexCoords
Pieter Geerkens edited this page Apr 6, 2019
·
2 revisions
The implementation of the User and Canon coordinate systems is in a single struct HexCoords.
There are several, but they all devolve to these two and a single private instance constructor, plus two static transformation matrices between the User and Canon coordinate systems.
/// <summary>Create a new instance at the specified vector offset as interpreted in the Canon(ical) frame.</summary>
public static HexCoords NewCanonCoords (IntVector2D vector)
=> new HexCoords(vector, vector * _matrixCanonToUser);
/// <summary>Create a new instance at the specified vector offset as interpreted in the Rectangular (User) frame.</summary>
public static HexCoords NewUserCoords (IntVector2D vector)
=> new HexCoords(vector * _matrixUserToCanon, vector);
private HexCoords(IntVector2D canon, IntVector2D user) :this() {
Canon = canon;
User = user;
}
static readonly IntMatrix2D _matrixUserToCanon = new IntMatrix2D(2, 1, 0,2, 0,0, 2);
static readonly IntMatrix2D _matrixCanonToUser = new IntMatrix2D(2,-1, 0,2, 0,1, 2);
Note that for simplicity both the User and Canon coordinate values are immediately stored for every instance. The algebraic work is delegated to an implementation of integer linear algebra in the two structs IntVector2D and IntMatrix2D.
/// <summary>Returns an <c>IntVector2D</c> representing the Canonical (obtuse) coordinates of this hex.</summary>
public IntVector2D Canon { get; }
/// <summary>Returns an <c>IntVector2D</c> representing the User (rectangular) coordinates of this hex.</summary>
public IntVector2D User { get; }
/// <summary>Modified <i>Manhattan</i> distance of supplied coordinate from the origin.</summary>
public int RangeFromOrigin => EmptyCanon.Range(this);
An example of the value of Canon(ical) coordinates is the calculation of the range between two hexes:
/// <summary>Modified <i>Manhattan</i> distance of supplied coordinate from this one.</summary>
public short Range(HexCoords coords) {
var deltaX = coords.Canon.X - Canon.X;
var deltaY = coords.Canon.Y - Canon.Y;
return (short) ( ( Math.Abs(deltaX) + Math.Abs(deltaY) + Math.Abs(deltaX-deltaY) ) / 2 );
}