Evolution of Colors - I

I do have a fascination with evolution and I like the idea of mutations. So one day I decided to "evolve" colors into another color. This project took me into the deep realms of Matplotlib and Numpy, so I believe it is worth sharing. 

First the question arises, how do we evolve colors. My approach was that, that every color is made up of 3 different amounts of the red, green and blue. In computer graphics this range is limited till only 255, since then we would have 256 values for red, green and blue each, which is also equal to 28, which is a number that can easily be stored by computers binary. Now we can mutate or change the values of red, green and blue of a color on a regular interval of time. Since, we want this to run "forever", mutating only may be an ideal option and keeping an end point may not be good. 

This was coded in Python using the Pyglet library.

Setting up the Scene

Let us first create a window in Pyglet and set the things up. I like keeping an alias for the libraries I import.

import pyglet as pt, random as r

window = pt.window.Window(500, 500, "Evolving Colors", True)
batch = pt.graphics.Batch()
background = pt.shapes.Rectangle(0, 0, window.width, window.height, batch=batch)

def update(dt):
    pass

pt.clock.schedule_interval(update, 1/60)

@window.event
def on_resize(width, height):
    background.width = window.width
    background.height = window.height 
    
@window.event
def on_draw():
    window.clear()
    batch.draw()

pt.app.run()

Mutating

One thing to note is that Pyglet takes in a tuple with length of 3 as a value for the color of any shape and we also know that tuple are immutable, meaning that once we assign a tuple its values, we cannot alter them. This poses as an obstacle for us while we are mutating, but we are also problem solvers. We can just create a list which will contain the rgb values of the color and work with that. Then we can just simply convert that list into a tuple. 

Before our update function we write this. We begin by setting random value for each of our rbg values.

colorsTuple = (r.randint(0, 255), r.randint(0, 255), r.randint(0, 255))
colors = list(colorsTuple)
background.color = colorsTuple

In our update function now we can mutate these colors! We begin by looping over our colors list and mutating them by adding or subtracting a random number from them. Let us assume that our red value is 254. If we add 2 to this, which will be purely random, the number which we will get will be 256 and this value cannot be accepted by Pyglet! Thus, we must only subtract a number when our rgb values are close to 255 and only add number when they are close to 0 and we can add or subtract number between 0 and 255. This may take a while to digest.

Before doing so we must introduce another variable called 'index'. To understand where this will be used, we must understand  how we are mutating the numbers. We are doing so by randomly choosing a number between a range. If this range is between 0 and 2, then the only number that can be chosen are 0, 1 and 2. This means that for a number, let's say 100, to reach 200 for example, will have get 2 one-hundred times in row! In other words, the mutation rate will be slow. Although if we choose 10, then the same event can happen in 10 turns meaning that the rate of evolution will be much faster (for a better understanding look at the extras section). 

Therefore keeping this in mind I have used index as end point of the range of the random values. Furthermore, to allow subtraction we can just add negative numbers.

index = 10
def update(dt): 
    for i in range(len(colors)):
        if colors[i] >= (255-index):
            colors[i] -= r.randint(0, index)
        elif colors[i] <= index:
            colors[i] += r.randint(0, index)
        else:
            colors[i] += r.randint((-1 * index), index)

Now we can just make these values our background color.

    colorsTuple = tuple(colors)
    background.color = colorsTuple

Limitations 

If you run the above program, you will notice something weird. You will see something like this.


Now if you watch the video, you will realize that the colors are evolving perfectly, but they are not doing so smoothly. We can actually notice that the color is changing. In the next blog, we will tackle this problem and make the colors evolve smoothly.

Extras

To understand the use index better, I visualized the evolution of colors with various indexes over a period of of about 6000 frames.









Happy Coding!!

Comments

Most Popular Posts