Created
December 7, 2019 17:54
-
-
Save makoConstruct/5767e5ddc3048e396d76e10e703dd940 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// o o o o . . . | |
// o o o o o . . | |
// o o o o o o . | |
// o o o o o o o | |
// . o o o o o o | |
// . . o o o o o | |
// . . . o o o o | |
v2 hexify(v2 v){ return v2{v.x+v.y/2, v.y*SQRTTHREEQUAR}; } //from square to hex | |
v2 unhexify(v2 v){ return v2{v.x-v.y/SQRTTHREE, v.y/SQRTTHREEQUAR}; } //from hex to square | |
float v2::hexManhattanMagnitude() const { | |
v2 h = unhexify(*this); | |
float aw = ::abs(h.x); | |
float ah = ::abs(h.y); | |
return h.x*h.y > 0 ? | |
aw+ah : | |
max(aw,ah); | |
} | |
//names for the six hexagonal directions, represented in square form | |
Coord Award = Coord(-1,0); | |
Coord Wward = Coord(-1,1); | |
Coord Eward = Coord(0,1); | |
Coord Dward = Coord(1,0); | |
Coord Xward = Coord(1,-1); | |
Coord Zward = Coord(0,-1); | |
Coord nearestHex(v2 p){ | |
v2 swpr = unhexify(p); | |
Coord closestPoint = Coord(floor(swpr.x), floor(swpr.y)); | |
Coord previousClosestPoint = closestPoint; | |
float dist = (p - hexify(v2::from(closestPoint))).magnitudeSquared(); | |
auto tryThis = [&closestPoint, &dist, p](Coord against){ | |
float nd = (p - hexify(v2::from(against))).magnitudeSquared(); | |
if(nd < dist){ | |
dist = nd; | |
closestPoint = against; | |
} | |
}; | |
tryThis(Coord(previousClosestPoint.x+1, previousClosestPoint.y)); | |
tryThis(Coord(previousClosestPoint.x, previousClosestPoint.y+1)); | |
tryThis(Coord(previousClosestPoint.x+1, previousClosestPoint.y+1)); | |
return closestPoint; | |
} | |
//steadily spirals outwards over a hexagonal grid from (0,0) | |
struct HexSpiral { | |
u32 layer; | |
u32 leg; | |
u32 progress; | |
i32 x; | |
i32 y; | |
void reset(){ | |
layer = 0; | |
leg = 1; | |
progress = 0; | |
x = 0; | |
y = 0; | |
} | |
HexSpiral(){ reset(); } | |
void step(){ | |
if(layer == 0){ | |
y += 1; | |
layer = 1; | |
}else{ | |
switch(leg){ | |
case 0: | |
y += 1; | |
x -= 1; | |
break; | |
case 1: | |
x -= 1; | |
break; | |
case 2: | |
y -= 1; | |
break; | |
case 3: | |
x += 1; | |
y -= 1; | |
break; | |
case 4: | |
x += 1; | |
break; | |
default: | |
y += 1; | |
break; | |
} | |
progress += 1; | |
if(leg >= 5){ | |
if(progress > layer){ | |
layer += 1; | |
leg = 0; | |
progress = 1; | |
} | |
}else{ | |
if(progress == layer){ | |
leg += 1; | |
progress = 0; | |
} | |
} | |
} | |
} | |
static u32 withinLayer(u32 layer){ return 1 + 3*layer*(layer+1); } | |
v2 currentPos(){ return hexify(v2{(float)x,(float)y}); } | |
Coord currentHexCoord(){ return Coord(x,y); } | |
}; | |
static Coord hexDirFor(uint angle){ | |
switch(moduloIntProperly(angle,6)){ | |
case 0 : return DWard(); break; | |
case 1 : return EWard(); break; | |
case 2 : return WWard(); break; | |
case 3 : return AWard(); break; | |
case 4 : return ZWard(); break; | |
case 5 : return XWard(); break; | |
default: return DWard(); break; | |
} | |
} | |
//uses a mathematic angle system, starts pointing right, then goes anticlockwise | |
uint hexAngle() const { //assumes it's a unit hex Coord | |
if(y > 0){ | |
return x < 0 ? 2 : 1; | |
}else if(y == 0){ | |
return x < 0 ? 3 : 0; | |
}else{ | |
return x < 1 ? 4 : 5; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment