public DenseGrid Flip_WE() { DenseGrid new_grid = new DenseGrid(this.width, this.height, 0); DenseGrid.BlitFromAOntoB(this, new_grid, 0, 0); // Starting with the outmost and working towards center, // swap the contents of each paired vertical strip. for (int W_xx = 0; W_xx < new_grid.center_x(); W_xx++) // VERIFY: is this correct for even widths? { int E_xx = new_grid.max_x() - W_xx; for (int yy = 0; yy <= new_grid.max_y(); yy++) { int W_value = contents_at_XY(W_xx, yy); int E_value = contents_at_XY(E_xx, yy); new_grid.set_contents_at_XY(W_xx, yy, E_value); new_grid.set_contents_at_XY(E_xx, yy, W_value); } // for(yy) } // for(xx) return new_grid; }
public static DenseGrid BlitFromAOntoB(DenseGrid from_A, int from_x, int from_y, DenseGrid to_B, int to_x, int to_y, int blit_width, int blit_height) { // Blit from A onto B, with as many method arguments as possible. if (from_A == null) return null; if (to_B == null) return null; // The from_x,y are relative to the origin of from_A. if (from_x < from_A.min_x()) return null; // At least somewhat off-edge to the left if (from_x > from_A.max_x()) return null; // Entirely to the right if (from_y < from_A.min_y()) return null; // At least somewhat off-edge above if (from_y > from_A.max_y()) return null; // Entirely below // The to_x,y are relative to the origin of to_B. if (to_x + blit_width < to_B.min_x()) return null; // Entirely to the left if (to_x > to_B.max_x()) return null; // Entirely to the right if (to_y + blit_height < to_B.min_y()) return null; // Entirely above if (to_y > to_B.max_y()) return null; // Entirely below // The blit width/height are clipped to avoid needless looping. // Blit calls which overlap from_A or to_B are thus harmless. // Indeed, calls overlapping to_B are common and ordinary, // one reason being that from_A and to_B are often of different sizes. int max_from_w = Math.Min(from_A.max_x(), from_x + blit_width); int max_to_w = Math.Min(to_B.max_x(), to_x + blit_width); int max_width = Math.Min(max_from_w, max_to_w); blit_width = GridUtility2D.Clamp(blit_width, 1, max_width); int max_from_h = Math.Min(from_A.max_y(), from_y + blit_height); int max_to_h = Math.Min(to_B.max_y(), to_y + blit_height); int max_height = Math.Min(max_from_h, max_to_h); blit_height = GridUtility2D.Clamp(blit_height, 1, max_height); // Iterate over the cells of from_A, and copy non-blank cells onto to_B: for (int yy = 0; yy <= blit_height; yy++) { for (int xx = 0; xx <= blit_width; xx++) { // To find the from/to blit coordinates, // add in the x,y offsets for from_A and to_B: int from_ii = GridUtility2D.indexForXYW(from_x + xx, from_y + yy, from_A.width); int to_ii = GridUtility2D.indexForXYW(to_x + xx, to_y + yy, to_B.width); int contents = from_A.contents_at_XY(from_x + xx, from_y + yy); if (contents != 0) { // Non-zero, not a blank cell (blank cells are skipped) to_B.set_contents_at_XY(to_x + xx, to_y + yy, contents); } } // for (xx) } // for (yy) return to_B; // to_B has been modified }
public DenseGrid Flip_NS() { DenseGrid new_grid = new DenseGrid(this.width, this.height, 0); DenseGrid.BlitFromAOntoB(this, new_grid, 0, 0); // Starting with the outmost and working towards center, // swap the contents of each paired horizontal strip. for (int N_yy = 0; N_yy < new_grid.center_y(); N_yy++) // VERIFY: is this correct for even heights? { int S_yy = new_grid.max_y() - N_yy; for (int xx = 0; xx <= new_grid.max_x(); xx++) { int N_value = contents_at_XY(xx, N_yy); int S_value = contents_at_XY(xx, S_yy); new_grid.set_contents_at_XY(xx, N_yy, S_value); new_grid.set_contents_at_XY(xx, S_yy, N_value); } // for(yy) } // for(xx) return new_grid; }