A practical explanation of colour

In my last post I talked about how certain building blocks of knowledge can make a lot of different tasks easier. I thought I’d go into a couple of building blocks that have helped me to do interesting things with colours.

Colours: What are they?

The first thing to understand is what colours – primary and secondary – actually are. When colours are made of light on a screen, the primary colours are red, green and blue (RGB). We’re told from childhood that they’re red, yellow and blue, but they’re not. People who have used computers a lot are used to this, but it’s surprising how many people aren’t.

The secondary colours are Cyan, Magenta and Yellow.

Green + Blue = Cyan
+ =

Red + Blue = Magenta
+ =

and Red + Green = Yellow (somewhat bizarrely)
+ =

full Red +  full Green + full Blue = White
+ + =

The sooner you accept these things, the happier you will be.

Understanding colours as numbers

Because colours on a computer are represented by numbers, it helps to keep in mind what those numbers are. The range for colour values is either between between 0 and 255 or 0.0 and 1.0. The 0.0-1.0 range can be thought of as a percentage: 0.8, 0.2, 0.9 would be 80% red, 20% green and 90% blue – a bright purple which is slightly more blue than it is red . Numbers in the range 0-255 are the same, so 0 is none of the colour, 128 is half, and 255 is full.

If bright yellow is all red + all green, that would mean it’s (255, 255, 0) . A dark blue would be no red and no green, with just a little blue – maybe something like (0, 0, 64).

So why does this matter?
If you want to be able to write code that generates colours, you need to know what the components of that colour are and what kind of number represents them. Next, we’ll look at how to use math to generate these numbers.

Some basic functions

The three math functions that I use the most are

  1. the random number generator
  2. rounding, and
  3. trigonometry functions.

The random number generator and rounding

The first is simple – it takes no input, and produces a different random number between 0 and 1 every time you use it – 0.2114, 0.7435 etc. If you wanted a random number anywhere between 1 and 10, you could just multiply by 10. If you wanted to simulate flipping a coin – heads or tails with nothing in between – you’d need to round this result to the nearest whole number, and say that 0 is tails and 1 is heads. In JavaScript, that would look like:

var coinFlip = Math.round(Math.random()); //this will give 0 or 1

Alternatively, you could simulate dice by multiplying by six and cutting off the decimal with Math.floor():
var diceThrow = Math.floor(Math.random()*6); //this will give a result of 0-5

floor() is like round() but always rounds down. There’s also ceil(), short for ceiling, which will always round up. We could use that to give a result of 1-6 instead:
var diceThrow = Math.ceil(Math.random()*6); //this will give a result of 1-6
It’s useful to be able to do both, since so many things in programming are zero-indexed.
If you wanted a totally random colour, you could ‘floor’ three random numbers between 0 and 255:

var randomRed = Math.floor(Math.random()*256); //this will give a result of 0-255
var randomGreen = Math.floor(Math.random()*256); //this will give a result of 0-255
var randomBlue = Math.floor(Math.random()*256); //this will give a result of 0-255

Sine and Cosine

The Sine and Cosine function are actually used to describe the components of an angle, but when you’re making colours the most useful aspect of them is that they take an input that increases at a constant rate (like the current time) and turn it into something that bounces back between -1 and 1. That means a function like this:

Turns into this:

This is great, but we need to change it a little to make a colour. If we wanted to make a colour with it, we’d need to do a couple of things. First, the function goes between -1 and +1. A colour needs to be between 0 and 255. First, we could add 1 to make the function go between 0 and 2:

Next, we need to shift it into the range of 0-255. You can think of that as first getting it into the range of 0-1 by dividing it by 2,

and then multiplying by 255 again to get it to cover the full range. The code for that would be:
var output = (1+Math.sin(input))/2*255;

Great! Now if you wanted to make a pulsing red colour, you could use time as the input and set the ‘r’ part of the output to be the output:

var redOutput = (1+Math.sin(input))/2*255;

To make a shade of grey, just make the red, green and blue values all the same:

var redOutput = (1+Math.sin(input))/2*255;
var greenOutput = (1+Math.sin(input))/2*255;
var blueOutput = (1+Math.sin(input))/2*255;

That would look like this:

Sine has a couple of interesting features, though: the wavelength, and the offset or phase. Wavelength is the time it takes for the pattern to repeat itself, so if we’re making a colour out of it, it could be the time it takes for that colour to return to white after going dark. You’d change the wavelength by multiplying the input value:

var slowOutput = (1+Math.sin(input))/2*255;
var fastOutput = (1+Math.sin(input * 10 ))/2*255; //changes ten times as fast as slowOutput

You could make a colour where the red changes slowly, the green changes faster and the blue changes even faster:
var redOutput = (1+Math.sin(input))/2*255;
var greenOutput = (1+Math.sin(input*2))/2*255;
var blueOutput = (1+Math.sin(input*3))/2*255;

That looks like this

The offset, or phase is how far ahead or behind that pattern is from the standard sine wave. You can think of it like a clock running early or late – it goes at the same speed as a clock telling the right time, and always stays different by the same amount. You get this effect/number(?) by adding some consistent amount to input. If you wanted the red, green and blue parts of a colour to change at the same speed but always stay different values, you might do this:

var redOutput = (1+Math.sin(input))/2*255;
var greenOutput = (1+Math.sin(input+1))/2*255;
var blueOutput = (1+Math.sin(input + 2))/2*255;

and that looks like this

So now you can make colours! In a future post I’ll go into how to think of adjusting the range and probability distribution of random numbers, tweaking the shape of a sine wave with exponents, and some advice on understanding hexadecimal.

One thought on “A practical explanation of colour”

Comments are closed.