// BoxFitter class // David Bollinger, July 2006 // http://www.davebollinger.com // for Processing 0115 beta // class BoxFitter { int wid, hei; int cols, rows; int col, row; int divx, divy; int maxsizer; int seed; // cells store the box fit pattern, contents are byte encoded as: // (cell >> 16) & 0xff == work to do // (cell) & 0xffff == size of allocated area int [][] cells; // the types of work that may occur in a cell static final int WORK_NONE = 0; static final int WORK_DONE = 1; BoxFitter(int _wid, int _hei, int _divx, int _divy, int _maxsizer) { wid = _wid; hei = _hei; // width AND height should be evenly divisible by divx/y divx = _divx; divy = _divy; maxsizer = _maxsizer; // largest box is (maxsizer * max(divx,divy)) pixels cols = wid / divx; rows = hei / divy; // sanity checks if (maxsizer*divx > wid) maxsizer = wid/divx; if (maxsizer*divy > hei) maxsizer = hei/divy; // further sanity check? hopefully not necessary: // if ((rows>0xffff)||(cols>0xffff)) then too big for current encoding // allocate cells = new int[rows][cols]; } // reset the pattern grid void wipe() { for (int r=0; r= cols) { col = 0; row++; if (row >= rows) { row = 0; } } } // this would typically be overridden void render(int x1, int y1, int w, int h) { float area = w * h; float maxarea = (maxsizer*divx) * (maxsizer*divy); float gray = 64.0 + (area / maxarea) * 128.0; fill(color(gray,gray,gray)); rect(x1,y1,w,h); } // advance through the pattern and draw the next box void drawone() { boolean drawn = false; do { int cell = cells[row][col]; int work = (cell>>16) & 0xff; int sizer = (cell) & 0xffff; if (work != WORK_NONE) { int y1 = row*divy; int x1 = col*divx; int w = sizer * divx; int h = sizer * divy; render(x1,y1,w,h); drawn = true; } advance(sizer); if (at00()) return; } while (!drawn); } }