float phasorInc = 1.0 / 53030.0;
float phasorInc2 = 1.0 / 90000.0;
int nPointsPerFrame = 1000;
PVector getVCoordinates(PVector v, float d, float a) {
return new PVector(v.x + d * cos(a), v.y + d * sin(a));
float getAngleFromCenter(PVector v) {
return atan2(v.y - height / 2, v.x - width / 2);
Walker(float x, float y) {
float gauss = p2.phase * random(2);
v = getVCoordinates(v, gauss, angles[int(random(angles.length))]);
float offset = width / 4;
if (v.x >= width + offset) {
if (v.y >= height + offset) {
float a = getAngleFromCenter(v);
float d = dist(v.x, v.y, width / 2, height / 2);
PVector center = new PVector(width / 2, height / 2);
float rAngle = PI / (float) nReflections;
fill(palette.getNorm(p.phase), map(d, 0, width, 64, 12));
gauss = max(0.5, gauss / 2);
for (int i = 0; i < nReflections; i++) {
float thisAngle = a + (TWO_PI / (float) nReflections) * i;
PVector thisV = getVCoordinates(center, d, thisAngle);
ellipse(thisV.x, thisV.y, gauss, gauss);
thisV = getVCoordinates(center, d, PI - thisAngle);
ellipse(thisV.x, thisV.y, gauss, gauss);
ArrayList<Integer> colors;
colors = new ArrayList<Integer>();
int index = (int) (p * colors.size());
color c1 = colors.get(index);
color c2 = colors.get((index + 1) % colors.size());
return lerpColor(c1, c2, p * colors.size() - index);
angles = new float[nAngles];
for (int i = 0; i < angles.length; i++) {
angles[i] = ((float) i / (float) nAngles) * TWO_PI;
w = new Walker(width / 2, height / 2);
p = new Phasor(phasorInc);
p2 = new Phasor(phasorInc2);
palette.add(color(11, 17, 13));
palette.add(color(44, 77, 86));
palette.add(color(195, 170, 114));
palette.add(color(220, 118, 18));
palette.add(color(189, 50, 0));
color c = palette.getNorm(0.0);
for (int i = 0; i < height; i++) {
stroke(lerpColor(color(32), color(0), (float) i / (float) height));
for (int i = 0; i < nPointsPerFrame; i++) {