xxxxxxxxxx
// generative, sin, cos, abs, sqrt, atan2, TWO_PI, ellipse
// A combination of Dan Anderson's "Final Snowflake", sketch #396703, and
// the 'mover' code from "Spinning Tops", sketch #151089.
// A tweak/fork (twork?) of "eternalMandalas".
// Sketch is three times faster in Java mode.
// Mouse click to toggle background black/white.
float x, y, ang, dst, s, h;
Mover c;
ArrayList<PVector> ribbon = new ArrayList<PVector>();
PVector r, a, b;
boolean isBlk = false;
void setup() {
size(500, 500);
colorMode(HSB, 360, 100, 100, 100);
strokeWeight(.5);
c = new Mover();
s = 2;
h = random(360);
}
void draw() {
if (isBlk) background(20);
else background(350);
noFill();
stroke(290);
strokeWeight(3);
rect(95, 95, 310, 310);
x = c.x2-width/2;
y = c.y2-height/2;
dst = sqrt(x*x + y*y);
ang = atan2(y, x);
for (float i = 0; i < TWO_PI; i += TWO_PI/4) {
x = width/2 + dst * cos(ang + i);
y = height/2 + dst * sin(ang + i);
r = new PVector(x, y);
ribbon.add(r);
x = width/2 + dst * cos(-ang + i);
y = height/2 + dst * sin(-ang + i);
r = new PVector(x, y);
ribbon.add(r);
if (ribbon.size() > 1500) {
for (int j = 0; j <= 2; j++) {
ribbon.remove(j);
}
}
for (int j = ribbon.size ()-1; j > 0; j--) {
a = ribbon.get(j);
fill(h, (j/50)+70, 100-(j/50));
noStroke();
ellipse(a.x, a.y, s, s);
}
}
c.move();
h = (h + .4)%360;
}
class Mover {
float x, y, x2, y2, ang, max, min, radius, incr;
int howFar, dir, dir2;
PVector pos, vel;
Mover() {
max = 1;
min = .75;
howFar = 100;
pos = new PVector(random(howFar, width-howFar), random(howFar, height-howFar));
vel = new PVector(random(-1, 1), random(-1, 1));
vel.normalize();
vel.mult(1.25);
dir = random(2) > 1 ? 1 : -1;
dir2 = random(2) > 1 ? 1 : -1;
incr = random(.04, .05);
}
void move() {
update();
boundsCheck();
}
void update() {
pos.add(vel);
fill(290);
ellipse(pos.x, pos.y, 10, 10);
ang += incr;
x = pos.x + 30 * cos(ang)*dir;
y = pos.y + 30 * sin(ang)*dir;
radius = 25 * sin(ang*0.5);
ellipse(x, y, 7.5, 7.5);
x2 = x + radius * sin(ang*2*dir2);
y2 = y + radius * cos(ang*2*dir2);
ellipse(x2, y2, 5, 5);
stroke(290);
strokeWeight(1);
line(pos.x, pos.y, x, y);
line(x2, y2, x, y);
}
void boundsCheck() {
if (pos.x > width-howFar) vel.x = -random(min, max);
else if (pos.x < howFar) vel.x = random(min, max);
if (pos.y > height-howFar)vel.y = -random(min, max);
else if ( pos.y < howFar)vel.y = random(min, max);
}
}
void mousePressed(){
isBlk = !isBlk;
}