Collatz Conjecture + Unit Circle

Inspired by this cool page, I decided to make my own Collatz Conjecture visualization. My first try looked a lot like what I saw in the Numberphile video, which was pretty good. But then I thought of trying something new by keeping the original rules and wrapping everything around a unit circle. This created 360 "branches", each showing a 1-degree turn.

Even though this new approach might not reveal any groundbreaking insights into the Collatz Conjecture, I had a lot of fun with it and got some interesting results. The number 327, in particular, had a really long and cool path in this version.

 1import java.util.*;
 2
 3int howMany = 361;
 4int howManyFrames = 9840; //2:44 @ 60FPS
 5int size=30;
 6
 7Stack[] stacks = new Stack[howMany];
 8Turtle[] turtles = new Turtle[howMany];
 9
10void setup() {
11  size(1080,1080, P3D);
12  //fullScreen(P3D);
13  background(0);
14  textAlign(LEFT, CENTER);
15  textSize(size);
16
17  for (int i = 0; i < howMany; i++) {
18    stacks[i] = new Stack();
19    collatz(i, stacks[i]);
20  }
21
22  for (int i = 0; i < howMany; i++) {
23    turtles[i] = new Turtle(width/4, height/4, stacks[i]);
24  }
25}
26
27public void collatz(int n, Stack s) {
28  s.add(n);
29  if (n == 1 || n==0) return;
30  else if (n % 2 == 0) collatz(n / 2, s);
31  else collatz(3*n + 1, s);
32}
33
34void draw() {
35  translate(width/2, height/2, -1750);
36  for (int i = 1; i < howMany; i++) {
37    float m = map(i, 0, howMany-2, 0, (float)Math.PI*2);
38    rotateZ(-m);  
39    turtles[i].crawl();
40    rotateZ(m);
41  }
42/*
43  if (frameCount<howManyFrames+1) {
44    saveFrame("frame-####.png");
45  } else {
46    exit();
47  }
48  */
49}
50
51void keyTyped() {
52
53
54  if (int(key) ==32) {
55    saveFrame("frame-####.png");
56  }
57}
 1class Turtle {
 2
 3  PVector v1;
 4  int counter;
 5  Stack values;
 6
 7  Turtle(float _x, float _y, Stack _values) {
 8    this.v1 = new PVector(_x, _y, 0);
 9    this.values = _values;
10    this.counter = 1;
11  }
12
13  void crawl() {
14
15    float rg = map(counter, 0, this.values.size(), 0, 255);
16    float b = map(frameCount, 0, howManyFrames, 0, 255);
17
18    if (counter<this.values.size()) {
19
20      int d = (int)this.values.get(this.counter);
21
22      //PVector v2 = PVector.fromAngle(degrees(d));
23      PVector v2 = PVector.fromAngle(radians(d));
24
25      this.v1.x += v2.x;
26      this.v1.y += v2.y;
27
28      stroke(0, 31);
29      fill(255-rg, rg, b);
30      ellipse(this.v1.x, this.v1.y, size, size);
31    } else {
32      //noStroke();
33      //fill(53, m, 255-m);
34      //ellipse(this.v1.x, this.v1.y, size, size);
35      //fill(255);
36
37      //text(this.values.get(0)+"", this.v1.x+size/2, this.v1.y);
38    }
39
40    if (frameCount%60==0) {
41      counter++;
42    }
43  }
44}