79 lines
2.1 KiB
C#
79 lines
2.1 KiB
C#
using System;
|
|
using System.Numerics;
|
|
|
|
namespace RobotAndDonkey.Game.Utils;
|
|
|
|
public record struct Hex(int X, int Y)
|
|
{
|
|
public static int Distance(Hex a, Hex b)
|
|
{
|
|
var (acx, acy, acz) = OffsetToCube(a);
|
|
var (bcx, bcy, bcz) = OffsetToCube(b);
|
|
return Math.Max(Math.Max(Math.Abs(acx - bcx), Math.Abs(acy - bcy)), Math.Abs(acz - bcz));
|
|
|
|
static (int, int, int) OffsetToCube(Hex hex)
|
|
{
|
|
var x = hex.X - (hex.Y - (hex.Y & 1)) / 2;
|
|
var z = hex.Y;
|
|
var y = -x - z;
|
|
return (x, y, z);
|
|
}
|
|
}
|
|
|
|
public static Hex FromWorld(Vector2 coords)
|
|
{
|
|
var cx = coords.X * MathF.Sqrt(3) / 3 - coords.Y / 3;
|
|
var cz = coords.Y * 2 / 3;
|
|
var cy = -cx - cz;
|
|
var rx = (int)MathF.Round(cx);
|
|
var ry = (int)MathF.Round(cy);
|
|
var rz = (int)MathF.Round(cz);
|
|
|
|
var xDiff = MathF.Abs(rx - cx);
|
|
var yDiff = MathF.Abs(ry - cy);
|
|
var zDiff = MathF.Abs(rz - cz);
|
|
|
|
if (xDiff > yDiff && xDiff > zDiff)
|
|
rx = -ry - rz;
|
|
else if (yDiff > zDiff)
|
|
ry = -rx - rz;
|
|
else
|
|
rz = -rx - ry;
|
|
|
|
var col = rx + (rz - (rz & 1)) / 2;
|
|
var row = rz;
|
|
return new(col, row);
|
|
}
|
|
|
|
public static Hex FromPixel(Vector2 coords, float size)
|
|
{
|
|
return FromWorld(new(coords.X / size, coords.Y / size));
|
|
}
|
|
|
|
public Hex GetNeighbour(EDirection direction)
|
|
{
|
|
var parity = Y & 1;
|
|
var dir = offsetDirections[parity, (int)direction];
|
|
return new(X + dir.X, Y + dir.Y);
|
|
}
|
|
|
|
public Vector2 ToWorld()
|
|
{
|
|
var x = MathF.Sqrt(3) * (X + 0.5f * (Y & 1));
|
|
var y = 3.0f / 2 * Y;
|
|
return new(x, y);
|
|
}
|
|
|
|
public Vector2 ToPixel(float size)
|
|
{
|
|
var w = ToWorld();
|
|
return new(w.X * size, w.Y * size);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"({X}, {Y})";
|
|
}
|
|
|
|
private static readonly Hex[,] offsetDirections = { { new(+1, 0), new(0, -1), new(-1, -1), new(-1, 0), new(-1, +1), new(0, +1) }, { new(+1, 0), new(+1, -1), new(0, -1), new(-1, 0), new(0, +1), new(+1, +1) } };
|
|
} |