Skip to content

Instantly share code, notes, and snippets.

@gajeam
Created January 30, 2020 05:48
Show Gist options
  • Save gajeam/39b2c7bd634a86ab74869748f1542c4d to your computer and use it in GitHub Desktop.
Save gajeam/39b2c7bd634a86ab74869748f1542c4d to your computer and use it in GitHub Desktop.
Snails
// Visualizes the solution for this Riddler problem, using Java and Processing
// https://fivethirtyeight.com/features/how-long-is-the-snails-slimy-trail/?ex_cid=the-riddler
int SHAPE_SIDES = 6;
float SHAPE_RADIUS = 100.0;
float SHAPE_X;
float SHAPE_Y;
float[][] snails = new float[SHAPE_SIDES][2];
float totalDistance = 0.0;
void setup() {
size(360, 240);
SHAPE_X = width * .5;
SHAPE_Y = height * .5;
// If I wasn't lazy, this code would be modularized ;)
int i = 0;
float angle = TWO_PI / SHAPE_SIDES;
for (float a = angle; a < TWO_PI; a += angle) {
float sx = SHAPE_X + cos(a) * SHAPE_RADIUS;
float sy = SHAPE_Y + sin(a) * SHAPE_RADIUS;
snails[i][0] = sx;
snails[i][1] = sy;
i++;
}
}
void draw() {
background(102);
pushMatrix();
translate(width*0.5, height*0.5);
polygon(0, 0, SHAPE_RADIUS, SHAPE_SIDES);
popMatrix();
float threshold = 1.0;
for (int i = 0; i < SHAPE_SIDES; i++) {
float[] startSnail = snails[i];
float[] destSnail = snails[(i+1)%SHAPE_SIDES];
float distance = dist(startSnail[0], startSnail[1], destSnail[0], destSnail[1]);
if (distance != 0.0) {
float speed = .8;
float x = lerp(startSnail[0], destSnail[0], speed/distance);
float y = lerp(startSnail[1], destSnail[1], speed/distance);
if (i == 0) {
totalDistance += dist(startSnail[0], startSnail[1], x, y);
}
if (abs(SHAPE_X - x) < threshold && abs(SHAPE_Y - y) < threshold) {
x = SHAPE_X;
y = SHAPE_Y;
}
snails[i][0] = x;
snails[i][1] = y;
}
}
for(float[]s : snails) {
snailPoint(s[0], s[1]);
}
pushMatrix();
textSize(32);
text(nf(totalDistance, 0, 2), 10, 30);
popMatrix();
}
void snailPoint(float x, float y) {
fill(204, 102, 0);
ellipse(x, y, 10, 10);
fill(200);
}
void polygon(float x, float y, float radius, int npoints) {
float angle = TWO_PI / npoints;
beginShape();
for (float a = 0; a < TWO_PI; a += angle) {
float sx = x + cos(a) * radius;
float sy = y + sin(a) * radius;
vertex(sx, sy);
}
endShape(CLOSE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment