Skip to content

Instantly share code, notes, and snippets.

@JoshuaSullivan
Created July 6, 2017 02:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshuaSullivan/e5f6f3a6e77890b84cf5826d0f6623cb to your computer and use it in GitHub Desktop.
Save JoshuaSullivan/e5f6f3a6e77890b84cf5826d0f6623cb to your computer and use it in GitHub Desktop.
Control systems coming online. Order is being established…
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