/// <summary> /// returns all tiles of a cone starting at a point with given direction, length and width /// </summary> /// ![yellow = origin , blue = direction, green/blue = cone tiles](GetTiles_Cone.png) public static List <Vector3Int> Cone(Vector3Int origin, Vector3Int targetDirection, float coneWidthHalfAngle, int coneLength) { Vector3 originCartesian = HexConverter.TileCoordToCartesianCoord(origin); IEnumerable <Vector3Int> ring = GetTiles.Ring(origin, coneLength, 1); HashSet <Vector3Int> cone = new HashSet <Vector3Int>(); foreach (Vector3Int target in ring) { Vector3 targetWorldPos = HexConverter.TileCoordToCartesianCoord(target); Vector3 lookWorldPos = HexConverter.TileCoordToCartesianCoord((origin + targetDirection)); float angle = Vector3.Angle(targetWorldPos - originCartesian, lookWorldPos - originCartesian); if (Mathf.Abs(angle) > coneWidthHalfAngle + 0.001) { continue; } List <Vector3Int> linePointsL = GetTiles.Line(origin, target, false, -0.00001f); //for more consistent results we use 2 lines, one slightly left of center List <Vector3Int> linePointsR = GetTiles.Line(origin, target, false, +0.00001f); //and this her slightly right of center cone.UnionWith(linePointsL); cone.UnionWith(linePointsR); } return(cone.ToList()); }
/// <summary> /// returns all tiles of a ring around center in order specified by parameters (startDirection, clockwise) /// </summary> public static List <Vector3Int> Ring(Vector3Int center, int radius, TileDirection startDirection = TileDirection.TopRight, bool clockwise = true) { if (radius < 1) { throw new System.ArgumentException("radius needs to be larger than 0"); } List <Vector3Int> ringTiles = new List <Vector3Int>(); System.Func <Vector3Int, Vector3Int, Vector3Int> rotationMethod; if (clockwise == true) { rotationMethod = GetTile.FromTileRotated60DegreeClockwise; } else { rotationMethod = GetTile.FromTileRotated60DegreeCounterClockwise; } Vector3Int startOfRing = center + (TileDirectionVectors[(int)startDirection] * radius); ringTiles.Add(startOfRing); Vector3Int[] ringCornerTiles = new Vector3Int[6]; ringCornerTiles[0] = startOfRing; for (int i = 1; i < 6; i++) { ringCornerTiles[i] = rotationMethod(center, ringCornerTiles[i - 1]); } for (int i = 0; i < 6; i++) { List <Vector3Int> tilesOfRingSegment = GetTiles.Line(ringCornerTiles[i], ringCornerTiles[(i + 1) % 6], false); ringTiles.AddRange(tilesOfRingSegment); } ringTiles.RemoveAt(ringTiles.Count - 1); return(ringTiles); }