std::vector<gns::point> local_map::get_points() const { std::vector<gns::point> out; for (unsigned int i = 0; i < m_grid.size(); i++) for (unsigned int j = 0; j < m_grid.size(); j++) if (m_grid(i, j) == cell::NONFREE) out.push_back(get_change().toPoint(pointi(i, j))); return out; }
void fill(grid<400>& g, pointi c, int r) { std::queue<pointi> open; std::set<pointi> close; open.push(pointi(0, 0)); while (not open.empty()) { pointi p = open.front(); open.pop(); if (close.find(p) != close.end()) continue; close.insert(p); if (g.valid(c.x + p.x, c.y + p.y) and (p.x * p.x + p.y * p.y <= r * r)) { g(c.x + p.x, c.y + p.y) = cell::FREE; open.push(pointi(p.x + 1, p.y)); open.push(pointi(p.x - 1, p.y)); open.push(pointi(p.x, p.y + 1)); open.push(pointi(p.x, p.y - 1)); } } }
bool pack_rectangle(int* px, int* py, int width, int height) // Find a spot for the rectangle in the current cache image. // Return true if there's a spot; false if there's no room. { // Nice algo, due to JARE: // // * keep a list of "candidate points"; initialize it with {0,0} // // * each time we add a rect, add its lower-left and // upper-right as candidate points. // // * search the candidate points only, when looking // for a good spot. If we find a good one, also try // scanning left or up as well; sometimes this can // close some open space. // // * when we use a candidate point, remove it from the list. // Consider candidate spots. for (int i = 0, n = s_anchor_points.size(); i < n; i++) { const pointi& p = s_anchor_points[i]; recti r(p.m_x, p.m_x + width, p.m_y, p.m_y + height); // Is this spot any good? if (is_rect_available(r)) { // Good spot. Scan left to see if we can tighten it up. while (r.m_x_min > 0) { recti r2(r.m_x_min - 1, r.m_x_min - 1 + width, r.m_y_min, r.m_y_min + height); if (is_rect_available(r2)) { // Shift left. r = r2; } else { // Not clear; stop scanning. break; } } // Mark our covered rect; remove newly covered anchors. add_cover_rect(r); // Found our desired spot. Add new // candidate points to the anchor list. add_anchor_point(pointi(r.m_x_min, r.m_y_max)); // lower-left add_anchor_point(pointi(r.m_x_max, r.m_y_min)); // upper-right *px = r.m_x_min; *py = r.m_y_min; return true; } } // Couldn't find a good spot. return false; }