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:
parent
81e612b75b
commit
6547d224e0
5 changed files with 35 additions and 47 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue