using System; using UnityEngine; namespace Core.Utilities { /// /// Structure to contain cubic coordinates for hexagonal grids. Provides a derived Z coordinate where /// z = x + y, providing a new third axis /// public struct HexPoint : IEquatable { /// /// X-coordinate of hexagon point /// public readonly int x; /// /// Y-coordinate of hexagon point /// public readonly int y; /// /// Z-coordinate of hexagon point. This value is derived from x and y /// public readonly int z; /// /// Calculates the magnitude of this Hex point vector (its hex distance from the origin /// public int magnitude { get { return (Mathf.Abs(x) + Mathf.Abs(y) + Mathf.Abs(z)) / 2; } } /// /// Initialize a new hex point with two x,y coordinates /// public HexPoint(int x, int y) { this.x = x; this.y = y; this.z = x + y; } /// /// Initialized a new hex point with x and z coordinates /// public static HexPoint FromXZ(int x, int z) { int y = z - x; return new HexPoint(x, y); } /// /// Initialized a new hex point with y and z coordinates /// public static HexPoint FromYZ(int y, int z) { int x = z - y; return new HexPoint(x, y); } public bool Equals(HexPoint other) { return other.x == x && other.y == y; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) { return false; } return obj is HexPoint && Equals((HexPoint) obj); } /// /// Simple hash multiplying by two primes /// public override int GetHashCode() { unchecked { return (x.GetHashCode() * 22447) ^ (y.GetHashCode() * 31); } } public override string ToString() { return string.Format("X: {0}, Y: {1}, Z: {2}", x, y, z); } /// /// Rotate the given hex point by 60 degrees counterclockwise, around the origin /// public static HexPoint RotateLeft(HexPoint original) { return new HexPoint(-original.y, original.z); } /// /// Rotate the given hex point by 60 degrees counterclockwise, around the given point /// public static HexPoint RotateLeft(HexPoint original, HexPoint origin) { return RotateLeft(original - origin) + origin; } /// /// Rotate the given hex point by 60 degrees clockwise, around the origin /// public static HexPoint RotateRight(HexPoint original) { return new HexPoint(original.z, -original.x); } /// /// Rotate the given hex point by 60 degrees clockwise, around the given point /// public static HexPoint RotateRight(HexPoint original, HexPoint origin) { return RotateRight(original - origin) + origin; } /// /// Rotate the given hex point by 120 degrees counterclockwise, around the origin /// public static HexPoint RotateLeft120(HexPoint original) { return new HexPoint(-original.z, original.x); } /// /// Rotate the given hex point by 120 degrees counterclockwise, around the the given point /// public static HexPoint RotateLeft120(HexPoint original, HexPoint origin) { return RotateLeft120(original - origin) + origin; } /// /// Rotate the given hex point by 120 degrees clockwise, around the origin /// public static HexPoint RotateRight120(HexPoint original) { return new HexPoint(original.y, -original.z); } /// /// Rotate the given hex point by 120 degrees clockwise, around the the given point /// public static HexPoint RotateRight120(HexPoint original, HexPoint origin) { return RotateRight120(original - origin) + origin; } /// /// Rotate the given hex point 180 degrees around the origin /// public static HexPoint Rotate180(HexPoint original) { return new HexPoint(-original.x, -original.y); } /// /// Rotate the given hex point 180 degrees around the the given point /// public static HexPoint Rotate180(HexPoint original, HexPoint origin) { return Rotate180(original - origin) + origin; } /// /// Reflect the given hex point around the x-axis /// public static HexPoint ReflectX(HexPoint original) { int x = original.z; int y = -original.y; return new HexPoint(x, y); } /// /// Reflect the given hex point around the line where y is the given value /// public static HexPoint ReflectX(HexPoint original, int y) { var offset = new HexPoint(0, y); return ReflectX(original - offset) + offset; } /// /// Reflect the given hex point around the y-axis /// public static HexPoint ReflectY(HexPoint original) { int x = -original.x; int y = original.z; return new HexPoint(x, y); } /// /// Reflect the given hex point around the line where x is the given value /// public static HexPoint ReflectY(HexPoint original, int x) { var offset = new HexPoint(x, 0); return ReflectY(original - offset) + offset; } /// /// Reflect the given hex point around the z-axis /// public static HexPoint ReflectZ(HexPoint original) { int x = -original.y; int y = -original.x; return new HexPoint(x, y); } /// /// Reflect the given hex point around the line where z is the given value /// public static HexPoint ReflectZ(HexPoint original, int z) { var offset = FromXZ(0, z); return ReflectZ(original - offset) + offset; } // Math operators and conversions // Equality operators public static bool operator ==(HexPoint left, HexPoint right) { return left.Equals(right); } public static bool operator !=(HexPoint left, HexPoint right) { return !left.Equals(right); } // Conversion to and from IntVector2 public static explicit operator IntVector2(HexPoint hexPoint) { return new IntVector2(hexPoint.x, hexPoint.y); } public static explicit operator HexPoint(IntVector2 vector) { return new HexPoint(vector.x, vector.y); } // Math operators public static HexPoint operator +(HexPoint left, HexPoint right) { return new HexPoint(left.x + right.x, left.y + right.y); } public static HexPoint operator -(HexPoint left, HexPoint right) { return new HexPoint(left.x - right.x, left.y - right.y); } public static HexPoint operator *(int scale, HexPoint right) { return new HexPoint(right.x * scale, right.y * scale); } public static HexPoint operator *(HexPoint left, int scale) { return new HexPoint(left.x * scale, left.y * scale); } public static HexPoint operator -(HexPoint left) { return new HexPoint(-left.x, -left.y); } } }