I have always had this profound curiosity for nature and the amazing patterns that hide in all sorts of places. This, combined with my slight OCD and passion for computer programming, lead to the creation of my first complete program. The first program that I have ever made without being ordered to by a professor.
So you are probably thinking, What is Phyllotaxis?
In botany, phyllotaxis is the arrangement of leaves on a plant stem which form a distinctive class of patterns in nature. You can find examples of these patterns almost anywhere you go outside.
First we need to look at the math used in this problem. It turns out that there are a ton of mathematical relationships seen within the scope of phyllotaxis; The number of spirals that can be traced out through a phyllotactic pattern are primarily integers of the Fibonacci sequence. We can use this information to construct a mathematical model for this phenomenon. The ratios of consecutive Fibonacci numbers converge toward the golden ratio, which means that the ratio of those two numbers is the same as the ratio of their sum to the larger of the two quantities. From this we can deduce that the Fibonacci angle is roughly 137.5 degrees. This number, which we will call the divergence angle, will come into play later.
In order to recreate the patterns, we must use Vogel's Formula, which is:
a = n * divergenceAngle r = c * sqrt(n)
In this formula:
a is the the angle between a reference direction and the position vector of the nth dot.
n is is the ordering number of a dot, counting outward from the center.
r is the distance from the center of the canvas to the center of the dot.
c is a scaling factor that effectively changes the distance the dots are from the center and from each other.
The thing about this formula is that the angle and radius are in polar coordinates. So we need to convert this information into x and y coordinates. We can do this using polar-to-cartesian coordinate transformation (I really just like using that term because it sounds fancy). This is how we do that:
x = r * sin(a) y = r * cos(a)
Now we have the coordinates necessary to calculate where to place each dot in the animation. And this is what my first tackle at the code looked like.
def phyllotaxis_animate(): n = 0 c = 4 while(True): a = n * 137.5 r = c * math.sqrt(n) x = r * math.cos(a) + 200 y = r * math.sin(a) + 200 if(x >= 400 and y >= 400): break color = '#FFFFFF' outline = '#000000' canvas.create_oval(x, y, x + 8, y + 8, fill = color, outline = outline) n += 1 canvas.update()
This is the corresponding output:
Now I think this looks pretty cool, but I know that we can do more. I can go into the code and change the variables for the colors, but not everybody can do that. When my friend said that he wanted to play with it, but was very confused every time he tried changing around the variables, I knew what I wanted to do to take this to the next level.
I decided to create an intuitive user interface so that anyone could play around with this formula and make their own phyllotactic patterns. Every aspect of the formula is customizable from the divergence angle to the dot density.
What I found to be the most interesting part of this project is how to change the color of the dots. After much trial and error testing I eventually figured out the best way to change the colors and get some meaningful and interesting patterns out of it. For one, I had to use HSV values to set the colors for the dots. Using this color system allows me to carefully tune each aspect of each color. The hue changes the color, saturation changes the intensity, and luminosity changes the opacity. The problem here is that the tkinter Python library uses an RGB color scheme when drawing shapes. So I also had to use the colorsys library to translate the colors from HSV to RGB.
color_transfer = colorsys.hsv_to_rgb(1, 1, 1) color = "#%02x%02x%02x" % (color_transfer*255, color_transfer*255, color_transfer*255)
The function hsv to rgb only takes values from 0 to 1, so it is necessary to multiply these values by 255 in order to get the correct values for the final RGB color code. This above code makes all of the dots red. Changing the values given in the hsv to rgb will subsequently change the values in the RGB color code. So how do we use the variables that we have to change the color?
At our disposal we have the variables a, n, r, x, and y. We can add, subtract, multiply and divide all of these values together and use the result to change each of the HSV values. But in this program, I want the user to be able to choose what combination of variables and operators they would like to use, and manipulate the animation from there on. In order to do this I used list boxes to display all of the choices available to the user. From here they are able to choose any permutation of choices that they desire.
Once the user inputs their choices, it is up to the program to piece it together. For each category, a string is created that represents the users input. That string is then passed as a parameter to the eval() function and is plugged into the formula. The code for the Hue category looks like this:
if h != 1 and mainColor == None: try: fh = (eval(h)%256)/256 except: fh = 1 canvas.errorMessage.config(text = "Division by zero, using default values") elif mainColor == None: fh = h
The evaluated string of h is modulated and divided by 256 so that we can get a value that is between 0 and 1, which can then be passed to the hsv to rgb function. In addition to this, I also offer the option of overriding the hue value with one color using the colorchooser library. The saturation and luminosity values still apply, and you can go back to using the hue value by clearing the color selection.
I touched up the user interface by adding an error message section at the bottom, so the user knows why any weird behaviors occur. When everything is put together, this is what the final product looks like:
Now anybody can create their own phyllotactic patterns! I had a ton of fun programming this project and hope that you, the reader, learned something about phyllotaxis or programming. To see the full code to my program, you can check it out here. But for now, I leave you with some of my favorite results from this program.
Subscribe to CSTHINGS
Get the latest posts delivered right to your inbox