/* * Copyright (c) 2006, Andrew V. Clifton * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The name of the copyright holder may not be used to endorse or promote * products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ANDREW V. CLIFTON ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ANDREW V. CLIFTON BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // Example ink implementation // Andy Clifton // 9-19-06 // //--------------------------------------------------------------- // Global variables int WIDTH = 256; int HEIGHT = 256; PImage buf1; PImage buf0; int[] rand = new int[10027]; int rand_index = -1; int current_buffer = 0; //---------------------------------------------------------------- // Utility functions //Returns a value from 0 to high-1 int trand(int high) { rand_index++; if(rand_index >= 10027) rand_index = 0; return rand[rand_index] % high; } // Returns the value of a cell in the current buffer int read_cell(int x, int y) { if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) return 0; if(current_buffer == 0) return buf0.pixels[x + y*WIDTH] & 0xFF; else return buf1.pixels[x + y*WIDTH] & 0xFF; } // Writes a value to a cell in the current buffer void write_cell(int x, int y, int val) { if(current_buffer == 0) buf1.pixels[x + y*WIDTH] = color(val,val,val); else buf0.pixels[x + y*WIDTH] = color(val,val,val); } void write_cell_alt(int x, int y, int val) { if(current_buffer == 0) buf0.pixels[x + y*WIDTH] = color(val,val,val); else buf1.pixels[x + y*WIDTH] = color(val,val,val); } // Plots a point on the canvas, using subtractive blending void plot(int x, int y, int val) { color t = get(x,y); val >>= 6; if(mouseButton == LEFT) set(x,y,color(red(t)-val-1,green(t)-val,blue(t)-val)); else set(x,y,color(red(t)-val,green(t)-val-1,blue(t)-val-1)); } int choose(int a, int b, int c, int d) { int t = trand(4); switch(t) { case 0: return a; case 1: return b; case 2: return c; case 3: return d; } return 0; } // ------------------------------------------------------------ void setup() { buf0 = new PImage(WIDTH,HEIGHT); buf1 = new PImage(WIDTH,HEIGHT); current_buffer = 0; size(WIDTH,HEIGHT); background(255,255,255); for(int i = 0; i < 10027; i++) rand[i] = (int)random(0,1<<15); } void mouseDragged() { if(mouseX >= 0 && mouseX < WIDTH && mouseY >= 0 && mouseY < HEIGHT) write_cell_alt(mouseX,mouseY,255); } void draw() { int v; // The current cell's value int new_v; int n,s,e,w; // The neighboring cell's values int ne,nw,se,sw; int x = 0, y = 0; for(y = 0; y < HEIGHT; y++) { nw = read_cell(x-1, y-1); n = read_cell(x,y-1); ne = read_cell(x+1,y-1); w = read_cell(x-1,y); e = read_cell(x+1,y); sw = read_cell(x-1,y+1); s = read_cell(x,y+1); se = read_cell(x+1,y+1); v = read_cell(x,y); for(x = 0; x < WIDTH; x++) { if(x > 0) { // Shift the neighborhood values nw = n; n = ne; w = v; v = e; sw = s; s = se; //Read new values ne = read_cell(x+1,y-1); e = read_cell(x+1,y); se = read_cell(x+1,y+1); } //Compute the new value of the cell new_v = max(v,choose(n,s,e,w)) - 2; new_v = max(0,new_v); //Clamp at 0 write_cell(x,y,new_v); //Test and plot if(new_v > 0) plot(x,y,new_v); } } //Swap the buffers current_buffer = current_buffer == 1 ? 0 : 1; }