Collatz Conjecture Python Script

Hi all

I am trying to learn Python and decided to try making a script to visualise the Collatz Conjecture as a study exercise. I somewhat succeeded in generating the branching lines I was going for, but as I am still learning, this left me with lots of questions.

  1. In order to get the multiple threads, and multiple Collatz sequences, I simply input a range rather than a unique integer to my x input. I am pretty happy with the way the output is organised, but I was wondering if there would be any advantage in making this input a single value (total number of threads) and integrating a for loop in the code to get the sequence for each individual thread? And how would you go about writing it?

  2. The way I am visualising it here, all the lines overlap as they converge down to the base point. I was wondering if there would be a way to avoid this? Maybe by adding a new function that would clean the sequences of duplicate numbers after a minimum duplicate is met? But that would leave me lost on how to create the starting lines for each new branch.

  3. I would like to control the length of the new lines by applying a multiplier to them depending on the iteration (ie. to make them progressively get shorter or longer with each iteration). Should I simply use rs.VectorScale and use i * scalefactor?
    Edit: This turned out to be much easier than I expected, I simply added rs.VectorScale at the beginning of my for loop after the creating the vector.

  4. And finally I would love to try and make this grow in 3 dimensions, but I am not sure what sort of rule could be set up for Z axis transformation, while maintaining the common values of each sequence aligned. Ideally I’d want to rotate the vector along x or y axis at each branching intersection, but I’m not sure how to go about doing that. Or maybe create the rotation depending on the value of the number in the sequence? That way common values would always rotate the same way? Would there be some way of avoiding branches from colliding?

And of course, if you have any suggestions on cleaning up the script making it more efficient in any way, I would also really appreciate it. I am still very much a beginner so writing everything out and making the code as explicit as possible helps me a lot, but all suggestions are welcome.


201229 - Collatz (13.0 KB)

import rhinoscriptsyntax as rs

#create collatz sequence
def collatzSeq(i):
    while i > 1:
        if i % 2 == 0:
            i = i // 2
            i = ((3*i) + 1) // 2

#create list to store sequence numbers
seqList = []


def collatzViz(sequence, startLine, evenRot, oddRot):
    for i in sequence:
        #find the start and end points of the input line
        endpt = rs.CurveEndPoint(newLines[-1])
        stpt = rs.CurveStartPoint(newLines[-1])
        #create a vector from end points
        vect = rs.VectorCreate(endpt, stpt)
        if i % 2 == 0:
            #define an even value for rotation
            #evenRot = -20
            vect = rs.VectorRotate(vect, evenRot, (0,0,1))
            #define an odd value for rotation
            #oddRot = 20
            vect = rs.VectorRotate(vect, oddRot, (0,0,1))

        ptadd = rs.PointAdd(endpt, vect)
        #create line and add to main list
        #call recursive function

#create list to store resulting lines
newLines = []

collatzViz(seqList, startLine, evenRot, oddRot)

a = seqList
b = newLines

not an answer to your questions but as I did look at that some years ago it could give you ideas. (20.9 KB)

Thanks Laurent! I will definitely take a close look at your script. I particularly like how you set it up with the nRecursions. I was curious though, did you make the illustration below with that same script? Is it in 2D as well?

Yes this was done in 2D. As I see there are not many comments in my code. It is not so complicated but I still don’t understand everything. I will look at it and try to put some comments. It is a good night work !

Here some 3D (2.5 D) view of shortest paths between the end of the network and the beginning. All paths are then offseted with Clipper, then transformed to surface then elevated and then colored.
It is more like what was published by Edmund Harris

Limit set to 10000 20deg and -20 deg*0.75 (34.8 KB)


Here some new illustrations, it is a good exercise for tree navigation. It remembers me the first algorithm I made for fault tree visualization some 25 years ago!

So I changed a bit the algorithm. Now I have 2 logic, a max number logic or a max number of recursion level. Blue dot = prime number
max number = 1000

Max Level = 15 (16 levels as I begin at 0)

I implemented some way to change the position of the “trunk”. There is a slider from 0 to 1, 0 on top, 0.5 on middle, 1 on the bottom

You’ll see on the bottom the power of the graph 2.

Collatz_LEGACY [Jan-01 '21, 2213].gh (46.9 KB)
A bit like this one

And also possible to transform it to a circle

Collatz_LEGACY [Jan-01 '21, 2234].gh (56.5 KB)

And some 3d version