// Pixel Spaceships // David Bollinger - July 2006 // http://www.davebollinger.com // for Processing 0115 beta // (updated for 0119 Beta) /** Click mouse to advance early to next pattern
*/ PixelSpaceshipFitter fitter; PixelSpaceship ship; miniMT rng; // want a slightly more robust rng for 32 significant bits int currentSeed = 0; void setup() { size(480,480,P3D); frameRate(30); fitter = new PixelSpaceshipFitter(480/16, 480/16); rng = new miniMT(); next(); } void mousePressed() { next(); } void next() { background(255); fitter.make(++currentSeed); } void draw() { fitter.drawone(); if (fitter.at00()) next(); } // the generator class PixelSpaceship { static final int cols = 12; static final int rows = 12; static final int EMPTY = 0; static final int AVOID = 1; static final int SOLID = 2; static final int COKPT = 3; // ::added to aid coloring int seed; int colorseed; // ::added to aid coloring int[][] grid; int xscale, yscale; int xmargin, ymargin; PixelSpaceship() { grid = new int[rows][cols]; xscale = yscale = 1; xmargin = ymargin = 0; } void recolor() { // ::added to aid coloring colorseed = rng.generate(); } int getHeight() { return rows*yscale + ymargin*2; } int getWidth() { return cols*xscale + xmargin*2; } void setMargins(int xm, int ym) { xmargin = xm; ymargin = ym; } void setScales(int xs, int ys) { xscale = xs; yscale = ys; } void setSeed(int s) { seed = s; } void wipe() { for (int r=0; r0) && (grid[r][c-1]==AVOID)) needsolid=true; if ((c0) && (grid[r-1][c]==AVOID)) needsolid=true; if ((r> 8; else if (r < 9) h = (colorseed & 0xff0000) >> 16; else h = (colorseed & 0xff000000) >> 24; colorMode(HSB); fill(h, mysat, mybri); rect(x1,y1,xscale,yscale); } else if (m == COKPT) { float mysat = sats[c]; float mybri = bris[r]+40; colorMode(HSB); int h = (colorseed & 0xff); fill(h, mysat, mybri); rect(x1,y1,xscale,yscale); } } } } } class PixelSpaceshipFitter { PixelSpaceship ship; int cols, rows; int col, row; int seed; // cells store the box fit pattern, contents are byte encoded as: // (cell >> 16) & 0xff == work to do // (cell) & 0xff == size of allocated area // (this somewhat odd encoding scheme is a remnant of the // fractal subdivision method used for the pixel robots t-shirt image) int [][] cells; // the types of work that may occur in a cell static final int WORK_NONE = 0; static final int WORK_DONE = 1; PixelSpaceshipFitter(int c, int r) { cols = c; rows = r; ship = new PixelSpaceship(); 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; } } } // advance through the pattern and draw the next robot void drawone() { boolean drawn = false; do { int cell = cells[row][col]; int work = (cell>>16) & 0xff; int sizer = (cell) & 0xff; if (work != WORK_NONE) { int y1 = 16*row; int x1 = 16*col; ship.setScales( sizer, sizer ); ship.setMargins( 2*sizer, 2*sizer ); ship.setSeed(rng.generate()); ship.generate(); ship.recolor(); ship.draw( x1, y1 ); drawn = true; } advance(sizer); if (at00()) return; } while (!drawn); } } // a minimal version of the Mersenne Twister class miniMT { private long seed; private static final int N = 624; private static final int M = 397; private static final int MATRIX_A = 0x9908b0df; private static final int UPPER_MASK = 0x80000000; private static final int LOWER_MASK = 0x7fffffff; private static final int TEMPERING_MASK_B = 0x9d2c5680; private static final int TEMPERING_MASK_C = 0xefc60000; private int mt[]; private int mti; private int mag01[] = { 0x0, MATRIX_A }; public miniMT() { this.setSeed(0); } public miniMT(long seed) { this.setSeed(seed); } public void setSeed(final long _seed) { seed=_seed; mt = new int[N]; mt[0]= (int)(seed & 0xfffffff); for (mti=1; mti>> 30)) + mti); mt[mti] &= 0xffffffff; } } public final int generate() { int y; if (mti >= N) { int kk; for (kk = 0; kk < N - M; kk++) { y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK); mt[kk] = mt[kk+M] ^ (y >>> 1) ^ mag01[y & 0x1]; } for (; kk < N-1; kk++) { y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK); mt[kk] = mt[kk+(M-N)] ^ (y >>> 1) ^ mag01[y & 0x1]; } y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK); mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1]; mti = 0; } y = mt[mti++]; y ^= y >>> 11; y ^= (y << 7) & TEMPERING_MASK_B; y ^= (y << 15) & TEMPERING_MASK_C; y ^= (y >>> 18); return y; } }