Created
July 6, 2017 02:13
-
-
Save JoshuaSullivan/e5f6f3a6e77890b84cf5826d0f6623cb to your computer and use it in GitHub Desktop.
Control systems coming online. Order is being established…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final int PILLAR_ORDER = 6; | |
final float PILLAR_WIDTH = 40.0; | |
final float PILLAR_HEIGHT = 20.0; | |
final float PILLAR_SPACING = 2.0; | |
final float GRAVITY = -1.0; | |
final float ELASTICITY = -0.6; | |
final float MAX_HEIGHT = 500.0; | |
final int TOTAL_RINGS = int(ceil(float(PILLAR_ORDER) / 2)); | |
final int DELAY = 200; | |
class Pillar { | |
float velocity, height, hue; | |
Pillar() { | |
velocity = 0.0; | |
height = 0.0; | |
hue = random(360.0); | |
} | |
void pop(float popVelocity) { | |
velocity += popVelocity; | |
} | |
void update() { | |
if (velocity == 0.0 && height == 0.0) { | |
// At rest. | |
return; | |
} | |
velocity += GRAVITY; | |
height += velocity; | |
if (height <= 0) { | |
// Bounce! | |
height = 0.0; | |
velocity *= ELASTICITY; | |
if (velocity < abs(GRAVITY)) { | |
velocity = 0.0; | |
} | |
} else if (height >= MAX_HEIGHT) { | |
// Bounce off ceiling. | |
height = MAX_HEIGHT; | |
velocity *= ELASTICITY; | |
} | |
} | |
void draw() { | |
if (height == 0.0 && velocity == 0.0) { | |
return; | |
} | |
float pw = PILLAR_WIDTH / 2.0; | |
float ph = PILLAR_HEIGHT / 2.0; | |
float h = round(height); | |
noStroke(); | |
color c; | |
if (h > 0.0) { | |
c = color(hue, 20, 100, 100); | |
fill(c); | |
quad(0, 0, -pw, -ph, -pw, -(h + ph), 0, -h); | |
c = color(hue, 40, 100, 100); | |
fill(c); | |
quad(0, 0, pw, -ph, pw, -(h + ph), 0, -h); | |
} | |
float hRatio = h / MAX_HEIGHT; | |
c = color(hue, 4 + 10 * hRatio, 100, 100); | |
fill(c); | |
quad(0, -h, -pw, -(h + ph), 0, -(h + pw), pw, -(h + ph)); | |
} | |
} | |
float[] offsets; | |
int pillarCount; | |
Pillar[] pillars; | |
Pillar[][] pillarGrid; | |
int lastPop = 0; | |
int popIndex = 0; | |
boolean animateRows = true; | |
void setup() { | |
size(300, 640); | |
colorMode(HSB, 360, 100, 100, 100); | |
pillarCount = PILLAR_ORDER * PILLAR_ORDER; | |
pillars = new Pillar[pillarCount]; | |
pillarGrid = new Pillar[pillarCount][pillarCount]; | |
for (int i = 0; i < pillarCount; i++) { | |
pillars[i] = new Pillar(); | |
} | |
int index = 0; | |
float rowCount = 0.0; | |
offsets = new float[pillarCount * 2]; | |
float pw = PILLAR_WIDTH / 2.0 + PILLAR_SPACING; | |
float ph = -(PILLAR_HEIGHT / 2.0 + PILLAR_SPACING); | |
for (int i = 0; i < PILLAR_ORDER; i++) { | |
float xOffset = float(i) * -pw; | |
for (int j = 0; j <= i; j++) { | |
// Calculate the offset for this pillar. | |
float x = j * (PILLAR_WIDTH + 2.0 * PILLAR_SPACING) + xOffset; | |
float y = rowCount * ph; | |
offsets[index * 2] = x; | |
offsets[index * 2 + 1] = y; | |
index++; | |
} | |
rowCount += 1.0; | |
} | |
for (int i = PILLAR_ORDER - 2; i >= 0; i--) { | |
float xOffset = float(i) * -pw; | |
for (int j = 0; j <= i; j++) { | |
float x = j * (PILLAR_WIDTH + 2.0 * PILLAR_SPACING) + xOffset; | |
float y = rowCount * ph; | |
offsets[index * 2] = x; | |
offsets[index * 2 + 1] = y; | |
index++; | |
} | |
rowCount+= 1.0; | |
} | |
int[] rowCounts = new int[PILLAR_ORDER]; | |
int gridLoops = 2 * PILLAR_ORDER - 1; | |
int pillarIndex = 0; | |
for (int i = 0; i < gridLoops; i++) { | |
// Place into the pillar grid; | |
int gridRow = min(i, PILLAR_ORDER - 1); | |
while (gridRow >= 0 && rowCounts[gridRow] < PILLAR_ORDER) { | |
int count = rowCounts[gridRow]; | |
pillarGrid[gridRow][count] = pillars[pillarIndex]; | |
rowCounts[gridRow]++; | |
pillarIndex++; | |
gridRow--; | |
} | |
} | |
float deltaHue = 360 / float(TOTAL_RINGS); | |
for (int i = 0; i < TOTAL_RINGS; i++) { | |
Pillar[] ring = getRing(i); | |
int ringCount = countForRing(i); | |
float hue = float(i) * deltaHue; | |
for (int j = 0; j < ringCount; j++) { | |
ring[j].hue = hue; | |
} | |
} | |
lastPop = millis(); | |
} | |
void draw() { | |
background(0, 0, 100, 100); | |
int now = millis(); | |
int timeSincePop = now - lastPop; | |
if (timeSincePop >= DELAY) { | |
Pillar[] group = animateRows ? getRow(popIndex) : getColumn(popIndex); | |
for (int i = 0; i < PILLAR_ORDER; i++) { | |
group[i].pop(12.0); | |
} | |
popIndex++; | |
lastPop = now; | |
if(popIndex == PILLAR_ORDER) { | |
popIndex = 0; | |
animateRows = !animateRows; | |
lastPop += 3 * DELAY; | |
} | |
} | |
pushMatrix(); | |
translate(150, 630); | |
for (int i = pillarCount - 1; i >= 0; i--) { | |
pushMatrix(); | |
float x = offsets[i * 2]; | |
float y = offsets[i * 2 + 1]; | |
translate(x, y); | |
pillars[i].update(); | |
pillars[i].draw(); | |
popMatrix(); | |
} | |
popMatrix(); | |
} | |
int countForRing(int index) { | |
int ringIndex = max(0, min(index, TOTAL_RINGS - 1)); | |
int i = PILLAR_ORDER - 2 * ringIndex; | |
int j = i - 2; | |
int total = i * i - j * j; | |
return total; | |
} | |
Pillar[] getRing(int index) { | |
int ringIndex = max(0, min(index, TOTAL_RINGS - 1)); | |
int itemsToReturn = countForRing(ringIndex); | |
int count = 0; | |
Pillar[] pillarsToReturn = new Pillar[itemsToReturn]; | |
int min = ringIndex; | |
int max = PILLAR_ORDER - ringIndex - 1; | |
for (int i = 0; i < PILLAR_ORDER; i++) { | |
for (int j = 0; j < PILLAR_ORDER; j++) { | |
if (i >= min && i <= max && j >= min && j <= max && (i == min || i == max || j == min || j == max)) { | |
pillarsToReturn[count] = pillarGrid[i][j]; | |
count++; | |
} | |
} | |
} | |
return pillarsToReturn; | |
} | |
Pillar[] getRow(int index) { | |
int pillarIndex = max(0, min(index, PILLAR_ORDER - 1)); | |
Pillar[] pillarsToReturn = new Pillar[PILLAR_ORDER]; | |
for (int i = 0; i < PILLAR_ORDER; i++) { | |
pillarsToReturn[i] = pillarGrid[i][pillarIndex]; | |
} | |
return pillarsToReturn; | |
} | |
Pillar[] getColumn(int index) { | |
int pillarIndex = max(0, min(index, PILLAR_ORDER - 1)); | |
Pillar[] pillarsToReturn = new Pillar[PILLAR_ORDER]; | |
for (int i = 0; i < PILLAR_ORDER; i++) { | |
pillarsToReturn[i] = pillarGrid[pillarIndex][i]; | |
} | |
return pillarsToReturn; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment