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}