Predetermined Color Sequences

Latest Comments

No comments to show.
Matrix-Tutorials

There are times when we want to create a pattern where we vary the color in a predetermined sequence. For example, take a look at the pattern below.

This pattern consists of the following color sequence: green, blue, red, cyan, purple, white, and yellow. There are different ways to go about doing this. We’ll discuss two approaches. In both approaches we will put all of the color in to a colors array and then select the colors from there. The first approach does this selection using a color_index variable as shown below.

from wc import *

canvas = Canvas()
colors = [ 'green', 'blue', 'red', 'cyan', 'purple', 'white', 'yellow' ]

color_index = 0
points = []
for y in range(canvas.height):
    for x in range(canvas.width):
        points.append(Point(x,y,colors[color_index]))
        color_index += 1
        if (color_index > 6):
            color_index = 0
canvas.add(points)

What is happening in this logic is that the color index is increasing in value from 0 until it reaches 6 at which point it resets. This means the value cycles in this manner: 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, etc… One improvement we can make here is to replace 6 with len(colors)-1 as shown below.

from wc import *

canvas = Canvas()
colors = [ 'green', 'blue', 'red', 'cyan', 'purple', 'white', 'yellow' ]

color_index = 0
points = []
for y in range(canvas.height):
    for x in range(canvas.width):
        points.append(Point(x,y,colors[color_index]))
        color_index += 1
        if (color_index > len(colors) - 1):
            color_index = 0
canvas.add(points)

While this approach works, it results in a lot of messy code around the management of the color index. It turns out there is a very efficient way to do this with something called the modulus operator.

Modulus Operator

The modulus operator uses the percent sign character %. It is basically a remainder function. Take a look at the examples below to get the idea of what it does.

ExpressionResult
5%21
8%32
9%30
14%54
9%72

You might be wondering how we would use this to solve our color index problem. Take a look at these additional examples of the modulus operator in action and perhaps you’ll see the connection.

ExpressionResultExpressionResult
0%707%70
1%718%71
2%729%72
3%7310%73
4%7411%74
5%7512%75
6%7613%76

Remember that our goal is to have the color index cycle through the values 0-6 repeatedly as we progress through the for-loop. Well it turns out that’s exactly the result we get when we use the modulus operator. So with that explanation, take a look at the code below and see if it makes sense to you.

from wc import *

canvas = Canvas()
colors = [ 'green', 'blue', 'red', 'cyan', 'purple', 'white', 'yellow' ]

color_index = 0
points = []
for y in range(canvas.height):
    for x in range(canvas.width):
        pixel_num = y * 16 + x
        points.append(Point(x,y,colors[pixel_num%len(colors)]))
canvas.add(points)

Notice that we don’t even need a color index variable anymore. This results in much less cluttered code.

Challenge Problem

Now let’s leverage what we learned about the modulus operator to do something more ambitious. Let’s define a pattern of lines that cycle through a predetermined list of colors and line lengths. Look at the image below and see if you can determine the repeating pattern.

The pattern is outlined in the table below.

ColorLength
Green2
Blue6
Red3
Cyan9
Purple5
White7
Yellow4

So how do we go about doing this? The approach taken below is to store the colors and lengths in two arrays (lines 4-5) and then track how long we have been painting a line with a certain color using a for range loop (line 12). Once we have completed the required repetitions we cycle to the next set of color (lines 20-22) and length values. We use a conditional (line 15) to test when we have reached the end of a row and advance to the next row (line 17) while resetting the column index to zero (line 16).

from wc import *

canvas = Canvas()
colors = [ 'green', 'blue', 'red', 'cyan', 'purple', 'white', 'yellow' ]
lengths = ( 2, 6, 3, 9, 5, 7, 4 )
color_index = 0
points = []
x = 0
y = 0
color_index = 0
while y < canvas.height:
    for count in range(lengths[color_index]):
        points.append(Point(x,y,colors[color_index]))
        x += 1
        if x == canvas.width:
            x = 0
            y += 1
            if y == canvas.height:
                break
    color_index += 1
    if (color_index == len(colors)):
        color_index = 0
canvas.add(points)

We can make this code even better by combining the sets of color and length values into a single set which has tuples of values. This makes the code more compact and also easier to follow.

from wc import *

canvas = Canvas()
colors = ( ('green',2), ('blue',6), ('red',3), ('cyan',9), ('purple',5), ('white',7), ('yellow',4) )
color_index = 0
points = []
x = 0
y = 0
color_index = 0
while y < canvas.height:
    for count in range(colors[color_index][1]):
        points.append(Point(x,y,colors[color_index][0]))
        x += 1
        if x == canvas.width:
            x = 0
            y += 1
            if y == canvas.height:
                break
    color_index += 1
    if (color_index == len(colors)):
        color_index = 0
canvas.add(points)

Tags:

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *