#include "grid.h" #include "gradient.h" #include void circle(int diameter, grid* out) { resize(diameter, diameter, out); int d2 = diameter * diameter; for (int x = 0; x < xsize(*out); ++x) { int dx = x * 2 - xsize(*out) + 1, x2 = dx * dx; for (int y = 0; y < ysize(*out); ++y) { int dy = y * 2 - ysize(*out) + 1, y2 = dy * dy; if (x2 + y2 < d2) (*out)[x][y] = 0; } } } void make(grid const& in, depth limit, tool* out) { if (!xsize(in) || !ysize(in)) return; grid rev = in; for (int x = 0; x < xsize(rev); ++x) std::reverse(rev[x].begin(), rev[x].end()); std::reverse(rev.begin(), rev.end()); coord pos; for (pos.y = 0; pos.y < ysize(in); ++pos.y) { bool state = false; for (pos.x = 0; pos.x < xsize(in); ++pos.x) { bool last = state; state = rev[pos.x][pos.y] < limit; if (state && !last) (*out)[RIGHT].push_back(pos); } state = false; for (pos.x = xsize(in) - 1; pos.x >= 0; --pos.x) { bool last = state; state = rev[pos.x][pos.y] < limit; if (state && !last) (*out)[LEFT].push_back(pos); } } for (pos.x = 0; pos.x < xsize(in); ++pos.x) { bool state = false; for (pos.y = 0; pos.y < ysize(in); ++pos.y) { bool last = state; state = rev[pos.x][pos.y] < limit; if (state && !last) (*out)[DOWN].push_back(pos); } state = false; for (pos.y = ysize(in) - 1; pos.y >= 0; --pos.y) { bool last = state; state = rev[pos.x][pos.y] < limit; if (state && !last) (*out)[UP].push_back(pos); } } } void make(tool const& tool, grid const& in, depth limit, gradient* out) { for (int i = 0; i < EDGES; ++i) { int xs = xsize(in), ys = ysize(in); for (size_t j = 0; j < tool[i].size(); ++j) { xs = std::max(xs, xsize(in) + tool[i][j].x); ys = std::max(ys, ysize(in) + tool[i][j].y); } resize(xs, ys, &(*out)[i], 0); } for (int x = 0; x < xsize(in); ++x) for (int y = 0; y < ysize(in); ++y) if (in[x][y] < limit) update(tool, x, y, 1, out); } void update(tool const& tool, int x, int y, int delta, gradient* out) { for (int i = 0; i < EDGES; ++i) { grid* g = &(*out)[i]; std::vector::const_iterator j, end = tool[i].end(); for (j = tool[i].begin(); j != end; ++j) (*g)[x + j->x][y + j->y] += delta; } } void mark(int x, int y, int xs, int ys, int delta, gradient* out) { for (int i = 0; i < EDGES; ++i) resize(std::max(x + xs, xsize((*out)[i])), std::max(y + ys, ysize((*out)[i])), &(*out)[i], 0); for (int i = 0; i < xs; ++i) { (*out)[UP][x + i][y + ys - 1] += delta; (*out)[DOWN][x + i][y] += delta; } for (int j = 0; j < ys; ++j) { (*out)[LEFT][x + xs - 1][y + j] += delta; (*out)[RIGHT][x][y + j] += delta; } } bool path::getdir() { dx = dy = 0; forward = backward = EDGES; more = 1; if (x < end_x) { dx = 1; backward = LEFT; if (x >= -1 && x < xsize(grad[RIGHT]) - 1 && y >= 0 && y < ysize(grad[RIGHT])) { forward = RIGHT; more = std::min(end_x, xsize(grad[RIGHT]) - 1) - x; } } else if (y < end_y) { dy = 1; backward = UP; if (x >= 0 && x < xsize(grad[DOWN]) && y >= -1 && y < ysize(grad[DOWN]) - 1) { forward = DOWN; more = std::min(end_y, ysize(grad[DOWN]) - 1) - y; } } else if (y > end_y) { dy = -1; backward = DOWN; if (x >= 0 && x < xsize(grad[UP]) && y >= 1 && y < ysize(grad[UP]) + 1) { forward = UP; more = y - std::max(0, end_y); } } else if (x > end_x) { dx = -1; backward = RIGHT; if (x >= 1 && x < xsize(grad[LEFT]) + 1 && y >= 0 && y < ysize(grad[LEFT])) { forward = LEFT; more = x - std::max(0, end_x); } } else { more = 0; return false; } return true; }