/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.fUr8IvmG6tF/rev.51
*
* authors:
* GoToLoop
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/**
* Grid Random Walkers (v2.3.0)
* by HowardCornwell (2014/Aug)
* mod GoToLoop
*
* Forum.Processing.org/two/discussion/6838/1d-array-affecting-2d-array#Item_4
* Studio.ProcessingTogether.com/sp/pad/export/ro.91FXxn8BG2fPL
*/
static final boolean JAVA = 1/2 != 1/2.;
static final int GRID = 20, DOTS = 4, FPS = 30;
final Box[][] grid = new Box[GRID][GRID];
final Point[] points = new Point[DOTS];
PImage bg;
void setup() {
size(800, 600);
smooth();
frameRate(FPS);
colorMode(HSB, Point.HUES, 1, 1);
rectMode(CORNER);
ellipseMode(CENTER);
strokeWeight(Point.WEIGHT);
stroke(Point.STROKE);
final int wg = width / GRID, hg = height / GRID;
BoxData.dx = wg - BoxData.GAP;
BoxData.dy = hg - BoxData.GAP;
for (int i = 0; i != DOTS; points[i++] = new Point());
for (int row = 0; row != GRID; ++row) for (int col = 0; col != GRID;
grid[row][col] = new Box(col++ * wg, row * hg));
bg = createGrid();
}
void draw() {
set(0, 0, bg);
for (final Point p : points) {
NextPoint:
for (final Box[] boxes : grid) for (final Box b : boxes)
if (p.isInside(b)) {
b.fillBox(p.hueColor);
break NextPoint;
}
p.script();
}
}
PImage createGrid() {
final PGraphics pg = createGraphics(width, height, JAVA2D);
pg.beginDraw();
pg.background(0);
pg.smooth();
pg.rectMode(CORNER);
pg.strokeWeight(BoxData.WEIGHT);
pg.stroke(BoxData.STROKE);
pg.noFill();
for (final Box[] boxes : grid) for (final Box b : boxes) b.drawBox(pg);
pg.endDraw();
return pg.get();
}
static abstract class BoxData {
static final int STROKE = -1, WEIGHT = 1, GAP = 5;
static int dx, dy;
}
final class Box extends BoxData {
final short x, y;
Box(final int xx, final int yy) {
x = (short) xx;
y = (short) yy;
}
void fillBox(final color c) {
fill(c, 1, 1);
rect(x, y, dx, dy);
}
void drawBox(final PGraphics pg) {
pg.rect(x, y, dx, dy);
}
}
final class Point {
static final int STROKE = 0, WEIGHT = 1, HUES = 360;
static final int DIAM = 8, SPD = 20, HUE_STEP = 2;
static final float NOISE_OFFSET = JAVA? .4538 : .467;
static final float MAX_NOISE_INC = JAVA? .2 : .15;
float x, y, xoff, yoff, inc;
color hueColor;
Point() {
reset();
}
void reset() {
noiseSeed((int) random(MAX_INT >> 6) * (second() + 1));
x = .5 * width;
y = .5 * height;
xoff = random(-SPD, SPD);
yoff = random(-SPD, SPD);
inc = random(-MAX_NOISE_INC, MAX_NOISE_INC);
hueColor = (int) random(HUES);
}
void script() {
move();
cycleHue();
display();
}
void move() {
x += SPD * (noise(xoff += inc) - NOISE_OFFSET);
y += SPD * (noise(yoff += inc) - NOISE_OFFSET);
if (x > width || x < 0 || y > height || y < 0) reset();
}
void cycleHue() {
hueColor = (hueColor + HUE_STEP) % HUES;
}
void display() {
fill(hueColor, 1, 1);
ellipse(x, y, DIAM, DIAM);
}
boolean isInside(final Box b) {
return x > b.x && x < b.x + Box.dx && y > b.y && y < b.y + Box.dy;
}
}