Circle iterator now compensates for the matrix size and won't overflow.
This commit is contained in:
parent
35f2defc11
commit
857cd2f910
5 changed files with 25 additions and 23 deletions
|
@ -7,17 +7,13 @@ using std::vector;
|
|||
namespace lighting {
|
||||
|
||||
void LightRender::render_circle_light(LightSource source, Point at, PointList &has_light) {
|
||||
for(matrix::circle it{at, source.distance + 1}; it.next();) {
|
||||
for(matrix::circle it{$lightmap, at, source.distance + 1}; it.next();) {
|
||||
for(int x = it.left; x < it.right; x++) {
|
||||
if(matrix::inbounds($paths.$paths, x, it.y) &&
|
||||
$paths.$paths[it.y][x] != WALL_PATH_LIMIT)
|
||||
{
|
||||
$lightmap[it.y][x] = light_level(source.strength, x, it.y);
|
||||
has_light.push_back({(size_t)x, (size_t)it.y});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LightRender::render_compass_light(LightSource source, Point at, PointList &has_light) {
|
||||
for(matrix::compass it{$lightmap, at.x, at.y}; it.next();) {
|
||||
|
|
15
matrix.cpp
15
matrix.cpp
|
@ -180,21 +180,24 @@ namespace matrix {
|
|||
}
|
||||
|
||||
|
||||
circle::circle(Point center, int radius) :
|
||||
circle::circle(Matrix &mat, Point center, int radius) :
|
||||
center(center), radius(radius)
|
||||
{
|
||||
top = max(center.y - radius, size_t(0));
|
||||
bottom = center.y + radius;
|
||||
width = matrix::width(mat);
|
||||
height = matrix::height(mat);
|
||||
top = max(int(center.y - radius), 0);
|
||||
bottom = min(int(center.y + radius), height);
|
||||
|
||||
y = top;
|
||||
}
|
||||
|
||||
bool circle::next() {
|
||||
y++;
|
||||
if(y <= bottom) {
|
||||
if(y < bottom) {
|
||||
dy = y - center.y;
|
||||
dx = floor(sqrt(radius * radius - dy * dy));
|
||||
left = center.x - dx;
|
||||
right = center.x + dx;
|
||||
left = max(0, int(center.x - dx));
|
||||
right = min(width, int(center.x + dx));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -127,8 +127,10 @@ namespace matrix {
|
|||
int right = 0;
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
circle(Point center, int radius);
|
||||
circle(Matrix &mat, Point center, int radius);
|
||||
void update();
|
||||
bool next();
|
||||
};
|
||||
|
|
|
@ -226,7 +226,7 @@ TEST_CASE("prototype line algorithm", "[matrix:line]") {
|
|||
}
|
||||
|
||||
TEST_CASE("prototype circle algorithm", "[matrix:circle]") {
|
||||
for(int count = 0; count < 20; count++) {
|
||||
for(int count = 0; count < 2000; count++) {
|
||||
size_t width = Random::uniform<size_t>(10, 13);
|
||||
size_t height = Random::uniform<size_t>(10, 15);
|
||||
int pos_mod = Random::uniform<int>(-3,3);
|
||||
|
@ -238,14 +238,17 @@ TEST_CASE("prototype circle algorithm", "[matrix:circle]") {
|
|||
// use an empty map
|
||||
Matrix result = map.walls();
|
||||
|
||||
for(matrix::circle it{start, radius}; it.next();) {
|
||||
for(matrix::circle it{result, start, radius}; it.next();) {
|
||||
for(int x = it.left; x < it.right; x++) {
|
||||
// println("top={}, bottom={}, center.y={}, dy={}, left={}, right={}, x={}, y={}", it.top, it.bottom, it.center.y, it.dy, it.left, it.right, x, it.y);
|
||||
if(matrix::inbounds(result, x, it.y)) {
|
||||
// println("RESULT {},{}", matrix::width(result), matrix::height(result));
|
||||
REQUIRE(it.y >= 0);
|
||||
REQUIRE(x >= 0);
|
||||
REQUIRE(it.y < int(matrix::height(result)));
|
||||
REQUIRE(x < int(matrix::width(result)));
|
||||
result[it.y][x] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// matrix::dump("RESULT AFTER CIRCLE", result, start.x, start.y);
|
||||
}
|
||||
|
|
|
@ -142,14 +142,12 @@ void WorldBuilder::generate() {
|
|||
$map.load_tiles();
|
||||
|
||||
Point center = $map.place_entity(1);
|
||||
for(matrix::circle it{center, 3}; it.next();) {
|
||||
for(matrix::circle it{$map.$walls, center, 3}; it.next();) {
|
||||
for(int x = it.left; x < it.right; x++) {
|
||||
if($map.inmap(x, it.y) && !$map.iswall(x, it.y)) {
|
||||
$map.$tiles.set_tile(x, it.y, "WATER_TILE");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldBuilder::make_room(size_t origin_x, size_t origin_y, size_t w, size_t h) {
|
||||
$map.INVARIANT();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue