Remove map_location::get_in_basis_N_NE

It was ONLY used in one place, to calculate rotate_right_around_center, and was likely not a very efficient way of calculating that anyway. I've included a different implementation of rotate_right_around_center that uses cubic coordinates.
This commit is contained in:
Celtic Minstrel 2024-09-07 15:53:57 -04:00 committed by Celtic Minstrel
parent 81e612b75b
commit 6547d224e0
5 changed files with 35 additions and 47 deletions

View file

@ -284,34 +284,25 @@ map_location::DIRECTION map_location::get_relative_dir(const map_location & loc,
}
}
std::pair<int,int> map_location::get_in_basis_N_NE() const {
map_location temp(*this);
std::pair<int, int> ret;
ret.second = temp.x;
temp = temp.get_direction(SOUTH_WEST,temp.x);
assert(temp.x == 0);
ret.first = -temp.y;
temp = temp.get_direction(NORTH,temp.y);
assert(temp.y == 0);
temp = temp.get_direction(NORTH, ret.first);
temp = temp.get_direction(NORTH_EAST, ret.second);
assert(temp == *this);
return ret;
}
map_location map_location::rotate_right_around_center(const map_location & center, int k) const {
map_location temp(*this);
temp.vector_difference_assign(center);
std::pair<int,int> coords = temp.get_in_basis_N_NE();
map_location::DIRECTION d1 = map_location::rotate_right(NORTH, k);
map_location::DIRECTION d2 = map_location::rotate_right(NORTH_EAST, k);
return center.get_direction(d1, coords.first).get_direction(d2, coords.second);
auto me_as_cube = to_cubic(), c_as_cube = center.to_cubic();
auto vec = cubic_location{me_as_cube.q - c_as_cube.q, me_as_cube.r - c_as_cube.r, me_as_cube.s - c_as_cube.s};
// These represent the 6 possible rotation matrices on the hex grid.
// These are orthogonal 3x3 matrices containing only 0, 1, and -1.
// Each element represents one row of the matrix.
// The absolute value indicates which (1-based) column is non-zero.
// The sign indicates whether that cell contains -1 or 1.
static const int rotations[6][3] = {{1,2,3}, {-2,-3,-1}, {3,1,2}, {-1,-2,-3}, {2,3,1}, {-3,-1,-2}};
int vec_temp[3] = {vec.q, vec.r, vec.s}, vec_temp2[3];
int i = ((k % 6) + 6) % 6; // modulo-clamp rotation count to the range [0,6)
assert(i >= 0 && i < 6);
#define sgn(x) ((x) < 0 ? -1 : 1) // Not quite right, but we know we won't be passing in a 0
for(int j = 0; j < 3; j++) vec_temp2[j] = sgn(rotations[i][j]) * vec_temp[abs(rotations[i][j])-1];
#undef sgn
vec.q = vec_temp2[0] + c_as_cube.q;
vec.r = vec_temp2[1] + c_as_cube.r;
vec.s = vec_temp2[2] + c_as_cube.s;
return from_cubic(vec);
}
bool map_location::matches_range(const std::string& xloc, const std::string &yloc) const

View file

@ -27,6 +27,12 @@ class variable_set;
struct wml_loc {};
/// Represents a map location in cubic hexagonal coordinates.
/// See <https://www.redblobgames.com/grids/hexagons/#coordinates-cube> for a more detailed explanation.
struct cubic_location {
int q, r, s;
};
/**
* Encapsulates the map of the game.
*
@ -142,8 +148,17 @@ struct map_location {
DIRECTION get_relative_dir(const map_location & loc, map_location::RELATIVE_DIR_MODE mode /*= map_location::RADIAL_SYMMETRY*/ ) const;
DIRECTION get_relative_dir(const map_location & loc) const; //moved the default setting to .cpp file for ease of testing
// Express as a vector in the basis N, NE. N, and NE may be obtained by zero.get_direction(NORTH), ...(NORTH_EAST), respectively.
std::pair<int,int> get_in_basis_N_NE() const;
cubic_location to_cubic() const {
int q = x;
int r = y - int((x - abs(x) % 2) / 2);
int s = -q - r;
return cubic_location{q, r, s};
}
static map_location from_cubic(cubic_location h) {
int x = h.q;
int y = h.r + int((h.q - abs(h.q) % 2) / 2);
return map_location(x, y);
}
// Rotates the map_location clockwise in 60 degree increments around a center point. Negative numbers of steps are permitted.
map_location rotate_right_around_center(const map_location & center, int k) const;

View file

@ -881,7 +881,6 @@ lua_kernel_base::lua_kernel_base()
{ "get_adjacent_hexes", &lua_map_location::intf_get_adjacent_tiles },
{ "get_hexes_in_radius", &lua_map_location::intf_get_tiles_in_radius },
{ "distance_between", &lua_map_location::intf_distance_between },
{ "get_in_basis_N_NE", &lua_map_location::intf_get_in_basis_N_NE },
{ "get_relative_dir", &lua_map_location::intf_get_relative_dir },
// Shroud bitmaps
{"parse_bitmap", intf_parse_shroud_bitmap},

View file

@ -201,22 +201,6 @@ int intf_distance_between(lua_State* L)
return 1;
}
/**
* Expose map_location get_in_basis_N_NE
*/
int intf_get_in_basis_N_NE(lua_State* L)
{
map_location l1;
if(!luaW_tolocation(L, 1, l1)) {
return luaL_argerror(L, 1, "expected a location");
}
std::pair<int, int> r = l1.get_in_basis_N_NE();
lua_pushinteger(L, r.first);
lua_pushinteger(L, r.second);
return 2;
}
/**
* Expose map_location get_relative_dir
* - Args 1, 2: Two locations

View file

@ -33,7 +33,6 @@ int intf_tiles_adjacent(lua_State*);
int intf_get_adjacent_tiles(lua_State*);
int intf_get_tiles_in_radius(lua_State*);
int intf_distance_between(lua_State*);
int intf_get_in_basis_N_NE(lua_State*);
int intf_get_relative_dir(lua_State*);
} // end namespace lua_map_location