enum edge { UP, DOWN, LEFT, RIGHT, EDGES }; struct coord { int x, y; }; typedef std::vector tool[EDGES]; typedef grid gradient[EDGES]; // gradient[edge][x][y] is the *gross increase* in overlap as the bit's // *lower right* corner *enters* x,y in the edge direction. to compute net, // subtract the *opposite* direction of the cell the bit's corner is *leaving*. void circle(int diameter, grid*); void make(grid const&, depth, tool*); void make(tool const&, grid const&, depth, gradient*); void update(tool const&, int x, int y, int delta, gradient*); void mark(int x, int y, int xs, int ys, int delta, gradient*); struct path { gradient const& grad; const int end_x, end_y; int x, y, dx, dy; edge forward, backward; path(gradient const& g, int x, int y, int end_x, int end_y): grad(g), end_x(end_x), end_y(end_y), x(x), y(y), more(1) { next(); } bool done() const { return more <= 0; } int amount() const { return forward == EDGES ? 0 : grad[forward][x][y]; } int net() const { return amount() - get(grad[backward], x - dx, y - dy, 0); } void next() { if (--more > 0 || getdir()) { x += dx; y += dy; } } private: int more; bool getdir(); }; static inline int net(gradient const& g, int sx, int sy, int end_x, int end_y) { int out = 0; for (path p(g, sx, sy, end_x, end_y); !p.done(); p.next()) out += p.net(); return out; }