//takes a hex and a direction and returns the two vectors of the positions of the //corners that make up the border between the hex and its neighbor in the given direction //in clockwise order private (Vector3, Vector3) GetCorners(HexMap.DIRECTION d, Hex h) { Vector3 pos = hexMap.GetGOFromHex(h).transform.position; //vectors to get us the corner from the hex transform position Vector3 n = pos + new Vector3(0, y, r); //north Vector3 ne = pos + new Vector3(w, y, z); //north east Vector3 se = pos + new Vector3(w, y, -z); //south east Vector3 s = pos + new Vector3(0, y, -r); //south Vector3 sw = pos + new Vector3(-w, y, -z); //south west Vector3 nw = pos + new Vector3(-w, y, z); //north west switch (d) { case HexMap.DIRECTION.NORTHEAST: return(n, ne); case HexMap.DIRECTION.EAST: return(ne, se); case HexMap.DIRECTION.SOUTHEAST: return(se, s); case HexMap.DIRECTION.SOUTHWEST: return(s, sw); case HexMap.DIRECTION.WEST: return(sw, nw); case HexMap.DIRECTION.NORTHWEST: return(nw, n); } return(Vector3.zero, Vector3.zero); }
public Hex GetNeighbor(HexMap.DIRECTION dir) { switch (dir) { case HexMap.DIRECTION.NORTHEAST: return(hexMap.GetHex(this.Q, this.R + 1)); case HexMap.DIRECTION.EAST: return(hexMap.GetHex(this.Q + 1, this.R)); case HexMap.DIRECTION.SOUTHEAST: return(hexMap.GetHex(this.Q + 1, this.R - 1)); case HexMap.DIRECTION.SOUTHWEST: return(hexMap.GetHex(this.Q, this.R - 1)); case HexMap.DIRECTION.WEST: return(hexMap.GetHex(this.Q - 1, this.R)); case HexMap.DIRECTION.NORTHWEST: return(hexMap.GetHex(this.Q - 1, this.R + 1)); } return(null); }
private HexMap.DIRECTION GetOppositeDirection(HexMap.DIRECTION dir) { switch (dir) { case HexMap.DIRECTION.WEST: return(HexMap.DIRECTION.EAST); case HexMap.DIRECTION.NORTHWEST: return(HexMap.DIRECTION.SOUTHEAST); case HexMap.DIRECTION.NORTHEAST: return(HexMap.DIRECTION.SOUTHWEST); case HexMap.DIRECTION.EAST: return(HexMap.DIRECTION.WEST); case HexMap.DIRECTION.SOUTHEAST: return(HexMap.DIRECTION.NORTHWEST); case HexMap.DIRECTION.SOUTHWEST: return(HexMap.DIRECTION.NORTHEAST); } return(0); }
public void UpdateCityBorders(City city, GameObject cityGO, Dictionary <City, GameObject> cityToGOMap, Dictionary <GameObject, City> goToCityMap) { List <Blob> blobs = new List <Blob>(); //make sure each city has a line renderer and reset them all //create a new blob for each city List <City> cities = cityToGOMap.Keys.ToList <City>(); foreach (City c in cities) { if (!borderLineRenderers.ContainsKey(c)) { LineRenderer borderLineRenderer; borderLineRenderer = GetNewLineRenderer(c); borderLineRenderers[c] = borderLineRenderer; } else { borderLineRenderers[c].enabled = false; } blobs.Add(new Blob(c, new HashSet <Hex>(c.GetHexes()))); } List <Blob> newBlobs = new List <Blob>(); bool[] merged = new bool[blobs.Count]; for (int i = 0; i < blobs.Count; i++) { if (merged[i]) { continue; } newBlobs.Add(blobs[i]); bool somethingMerged; do { somethingMerged = false; for (int j = i + 1; j < blobs.Count; j++) { Blob otherBlob = blobs[j]; if (blobs[i].hexes.Overlaps(otherBlob.hexes) && !merged[j]) { merged[j] = true; somethingMerged = true; blobs[i].hexes.UnionWith(otherBlob.hexes); } } } while (somethingMerged); } blobs = newBlobs; foreach (Blob blob in blobs) { Debug.Log("Drawing border for blob around city: " + blob.city.name); //hexes contained in this blob HashSet <Hex> hexes = blob.hexes; //hexes we've visited so far HashSet <Hex> visitedHexes = new HashSet <Hex>(); //need a hashset of positions for fast set operations and array because order matters List <Vector3> positions = new List <Vector3>(); HashSet <Vector3> posSet = new HashSet <Vector3>(); //find a hex on the edge of the blob. Hex currHex = hexes.First <Hex>(); while (hexes.Contains(currHex.GetNeighbor(HexMap.DIRECTION.NORTHEAST))) { currHex = currHex.GetNeighbor(HexMap.DIRECTION.NORTHEAST); } Debug.Log("Found a hex on the edge of the blob: " + currHex.CoordsString()); //until we get back to the starting hex HexMap.DIRECTION dir = HexMap.DIRECTION.SOUTHEAST; bool finished = false; while (!finished) { //start one edge clockwise of the direction we came from dir = GetOppositeDirection(dir); dir = GetNextClockwiseDirection(dir); //search clockwise checking if each neighbor is in the blob //if not, add the vertices for that edge to the list //if so, move to that hex while (!hexes.Contains(currHex.GetNeighbor(dir))) { //set a line position on the corners that make the border (Vector3, Vector3)corners = GetCorners(dir, currHex); //round values to we don't miss duplicates due to floating point error corners.Item1.x = (float)Math.Round((Decimal)corners.Item1.x, 3, MidpointRounding.AwayFromZero); corners.Item1.y = (float)Math.Round((Decimal)corners.Item1.y, 3, MidpointRounding.AwayFromZero); corners.Item1.z = (float)Math.Round((Decimal)corners.Item1.z, 3, MidpointRounding.AwayFromZero); corners.Item2.x = (float)Math.Round((Decimal)corners.Item2.x, 3, MidpointRounding.AwayFromZero); corners.Item2.y = (float)Math.Round((Decimal)corners.Item2.y, 3, MidpointRounding.AwayFromZero); corners.Item2.z = (float)Math.Round((Decimal)corners.Item2.z, 3, MidpointRounding.AwayFromZero); bool containsCorner1 = posSet.Contains(corners.Item1); bool containsCorner2 = posSet.Contains(corners.Item2); //check for exit condition if (containsCorner1 && containsCorner2 && visitedHexes.Contains(currHex)) { finished = true; break; } //otherwise make sure we don't add duplicates if (!containsCorner1) { positions.Add(corners.Item1); posSet.Add(corners.Item1); } if (!containsCorner2) { positions.Add(corners.Item2); posSet.Add(corners.Item2); } dir = GetNextClockwiseDirection(dir); Debug.Log("Checking direction: " + dir.ToString()); } visitedHexes.Add(currHex); currHex = currHex.GetNeighbor(dir); } //draw border for this blob LineRenderer borderLineRenderer = borderLineRenderers[blob.city]; borderLineRenderer.positionCount = positions.Count; borderLineRenderer.loop = true; borderLineRenderer.SetPositions(positions.ToArray()); borderLineRenderer.enabled = true; } }