Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Triangles in triangles in triangles in triangles in Processing
//
// Triangles in triangles in triangles in triangles…
// Created using Processing 3.5.3.
//
// Code by @marcedwards from @bjango.
//
// A GIF of this code can be seen here:
// https://dribbble.com/shots/6539126-Triangles-in-triangles
//
color back = #1e1033;
color col1 = #ffeb33;
color col2 = #ff3351;
color col3 = #33e2ff;
void setup() {
size(800, 600, P2D);
frameRate(30);
smooth(8);
noStroke();
}
void draw() {
background(0);
pushMatrix();
translate(width / 2, height / 2);
rotate(timeLoop(180) * TAU / 3.0 + TAU * 0.75);
float zoom = 1;
zoom += 9 * Ease.overSin(Ease.hermite5(Ease.inExp(timeRangeLoop(180, 0, 60, 0))));
zoom += 90 * Ease.overSin(Ease.hermite5(Ease.inExp(timeRangeLoop(180, 60, 120, 0))));
zoom += 900 * Ease.overSin(Ease.hermite5(Ease.inExp(timeRangeLoop(180, 120, 180, 0))));
zoom *= 1.2;
scale(zoom);
drawTriangles(back, col1, 10);
drawTriangles(back, col2, 1);
drawTriangles(back, col3, 0.1);
drawTriangles(back, col1, 0.01);
drawTriangles(back, col2, 0.001);
drawTriangles(back, col3, 0.0001);
popMatrix();
}
void drawTriangles(color triBG, color triOther, float scale) {
pushMatrix();
scale(scale, scale);
fill(triBG);
tri(0, 0, 20 * 10, 0);
fill(triOther);
triGrid(3, 20, 0);
popMatrix();
}
void tri(float x, float y, float radius, float angle) {
beginShape();
for (float i = 0; i < TAU; i += TAU / 3) {
float a = i + angle;
vertex(x + cos(a) * radius, y + sin(a) * radius);
}
endShape(CLOSE);
}
void triGrid(int iterations, float radius, float angle) {
for (int iteration = 3; iteration <= iterations * 3; iteration += 3) {
float r = radius * iteration;
for (float a = 0; a < TAU; a += TAU / 3) {
float starta = angle + a;
float enda = angle + a + TAU / 3;
for (int i = 0; i < iteration; i++) {
tri(lerp(cos(starta) * r, cos(enda) * r, i / float(iteration)),
lerp(sin(starta) * r, sin(enda) * r, i / float(iteration)), radius, 0);
}
}
}
}
float timeLoop(float totalframes, float offset) {
return (frameCount + offset) % totalframes / totalframes;
}
float timeLoop(float totalframes) {
return timeLoop(totalframes, 0);
}
float timeRangeLoop(float totalframes, float start, float end, float offset) {
if ((frameCount % totalframes) >= end + offset) {
return 1;
} else {
return (constrain(frameCount % totalframes, start, end) + offset) % abs(end - start) / abs(end - start);
}
}
static class Ease {
static public float overSin(float t, float split1, float split1amp, float split2, float split2amp) {
float start = map(constrain(t, 0, split1), 0, split1, 0, 1);
float middle = map(constrain(t, split1, split2), split1, split2, 0, 1);
float end = map(constrain(t, split2, 1), split2, 1, 0, 1);
start = Ease.inOutSin(start) * split1amp;
middle = Ease.inOutSin(middle) * (split2amp - split1amp);
end = Ease.inOutSin(end) * (1 - split2amp);
return start + middle + end;
}
static public float inOutSin(float t) {
return 0.5 - cos(PI * t) / 2;
}
static public float overSin(float t) {
return overSin(t, 0.55, 1.15, 0.85, 0.96);
}
static public float hermite5(float t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
static public float inExp(float t, float power) {
return pow(t, power);
}
static public float inExp(float t) {
return inExp(t, 2);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.