/// <summary> /// Get the corners of a QR-space rectangle containing every cell touching an XY-space rectangle. /// </summary> public static HexCoordModel[] CartesianRectangleBounds(Vector2 cornerA, Vector2 cornerB) { Vector2 min = new Vector2(Math.Min(cornerA.x, cornerB.x), Math.Min(cornerA.y, cornerB.y)); Vector2 max = new Vector2(Math.Max(cornerA.x, cornerB.x), Math.Max(cornerA.y, cornerB.y)); HexCoordModel[] results = { HexCoordModel.AtPosition(min), HexCoordModel.AtPosition(max) }; Vector2 pos = results[0].Position(); if (pos.y - 0.5f >= min.y) { results[0] += neighbors[4]; } else if (pos.x >= min.x) { results[0] += neighbors[3]; } pos = results[1].Position(); if (pos.y + 0.5f <= max.y) { results[1] += neighbors[1]; } else if (pos.x <= max.x) { results[1] += neighbors[0]; } return(results); }
/// <summary> /// Determines whether this hex is within a specified rectangle. /// </summary> /// <returns><c>true</c> if this instance is within the specified rectangle; otherwise, <c>false</c>.</returns> public bool IsWithinRectangle(HexCoordModel cornerA, HexCoordModel cornerB) { if (r > cornerA.r && r > cornerB.r || r < cornerA.r && r < cornerB.r) { return(false); } bool reverse = cornerA.O > cornerB.O; // Travel right to left. bool offset = cornerA.r % 2 != 0; // Starts on an odd row, bump alternate rows left. bool trim = Math.Abs(cornerA.r - cornerB.r) % 2 == 0; // Even height, trim alternate rows. bool odd = (r - cornerA.r) % 2 != 0; // This is an alternate row. int width = Math.Abs(cornerA.O - cornerB.O); bool hasWidth = width != 0; if (reverse && (odd && (trim || !offset) || !(trim || offset || odd)) || !reverse && (trim && odd || offset && !trim && hasWidth)) { width -= 1; } int x = (O - cornerA.O) * (reverse? -1: 1); if (reverse && odd && !offset || !reverse && offset && odd && hasWidth) { x -= 1; } return(x <= width && x >= 0); }
/// <summary> /// Distance between two hexes. /// </summary> public static int Distance(HexCoordModel a, HexCoordModel b) { return((a - b).AxialLength()); }