|
Post by wyliam on Apr 13, 2015 0:11:10 GMT
Any suggestions for finding all hexes that border a sea tile (coast line), or similar searches? Wondering if there's a faster way than iterate over the non-sea hexes, get all six adjacent hexes and determine if one of them is a sea type.
|
|
|
Post by khash on Apr 13, 2015 8:24:32 GMT
There is nothing build in for it. But if you need to do this search often I would store this and then update if map changes. You may consider storing this information within hex itself or creating dictionary for fast search. But it all depend on what you want to achieve with it.
|
|
|
Post by wyliam on Apr 15, 2015 2:38:47 GMT
Ah okay- I do that already, but for whatever reason it adds ~10 seconds to my load time for a new map. I'm using Hex radius 10 and chunk radius 2. Was hoping that there was something to tie into when the chunks were created.
|
|
|
Post by khash on Apr 15, 2015 9:03:56 GMT
10 seconds! wow it shouldn't take 10 miliseconds! ok can you post what do you do exactly? Also how do you specify sea hexes? is it random? or is there a pattern? Because maybe you may extract information about being nearby sea from pattern itself with no testing
|
|
|
Post by wyliam on Apr 16, 2015 14:41:50 GMT
// find all land that borders a coast
foreach (KeyValuePair<Vector3i, Hex> pair in HexWorld.instance.hexes)
{
Hex h = pair.Value;
// skip sea
if (h.terrainType.source.isSeaType) continue;
// get neighbors
List<Hex> neighbors = HexHelper.GetAdjacentHexes(HexCoordinates.GetHexCoordAt(new Vector2(worldPos.x, worldPos.z)));
// add neighbor to coast if they border a sea tile
if (neighbors.FirstOrDefault(n => n.terrainType.source.isSeaType) != null)
if (!h.isCoast)
HexHelper.coastal.Add(h);
yield return null;
}
static public List<Hex> GetAdjacentHexes(Hex center)
{
List<Hex> hexes = new List<Hex>();
// up 0, 1,-1
hexes.Add(GetDirection(center, Direction.up));
// up right 1, 0,-1
hexes.Add(GetDirection(center, Direction.upRight));
// dn right 1,-1, 0
hexes.Add(GetDirection(center, Direction.downRight));
// dn 0,-1, 1
hexes.Add(GetDirection(center, Direction.down));
// dn left -1, 0, 1
hexes.Add(GetDirection(center, Direction.downLeft));
// up left -1, 1, 0
hexes.Add(GetDirection(center, Direction.upLeft));
return hexes;
}
static public Hex GetDirection(Hex center, Direction direction)
{
// center 0, 0, 0
// --------------------------------
switch (direction)
{
case Direction.up:
// up 0, 1,-1
return (HexWorld.instance.hexes[center.position + Vector3i.up + Vector3i.back]);
case Direction.upRight:
// up right 1, 0,-1
return (HexWorld.instance.hexes[center.position + Vector3i.right + Vector3i.back]);
case Direction.upLeft:
// up left -1, 1, 0
return (HexWorld.instance.hexes[center.position + Vector3i.left + Vector3i.up]);
case Direction.down:
// dn 0,-1, 1
return (HexWorld.instance.hexes[center.position + Vector3i.down + Vector3i.forward]);
case Direction.downRight:
// dn right 1,-1, 0
return (HexWorld.instance.hexes[center.position + Vector3i.right + Vector3i.down]);
case Direction.downLeft:
// dn left -1, 0, 1
return (HexWorld.instance.hexes[center.position + Vector3i.left + Vector3i.forward]);
default: Print.Error("Did not get hex direction as requested"); return null;
}
}
|
|
|
Post by khash on Apr 16, 2015 15:39:31 GMT
Cool.
Ok so why do you have "HexCoordinates.GetHexCoordAt(new Vector2(worldPos.x, worldPos.z))"
All of it seems a bit big for me. Hmm, I will write code in forum so it may have some number of errors, but would give you some solution to try
//while world get created, add new hexes to dictionary AND to the list, as both of them have different advantages
void MarkCoast(List<Hex> listOfHexes) { List<Hex> water = listOfHexes.FindAll(o => o.terrainType.source.isSeaType); foreach(Hex h in water) { List<Vector3i> v = HexNeighbors.GetRange(h.position, 1, 1); if (HexWorld.instance.hexes.ContainsKey(v)) { Hex n = HexWorld.instance.hexes[v]; if (!HexWorld.instance.hexes[v].terrainType.source.isSeaType) { if (!n.isCoast){ HexHelper.coastal.Add(n); } } } } }
not sure what performance you will get, but you should never have to use a single second for such a thing. If you do then maybe you should record neighbors pointers during hex creation and then search over neighbors is faster or check if its ok to do search in coroutine. You may as well handle it in multiple threads or otherwise accelerate it but you shouldn't have this problem in the first place so I'm not sure what slowed you so much down! ;/
PS I assume that "HexHelper.coastal.Add" sets boolean for hex at "isCoast" and its not some hidden search in the getter
|
|