Thursday 7 May 2009

Sine in action - Part 2

Colouring and the getColor() function

In our main program, instead of plotting the sine function we are going to colour the surrounding pixels in relation to how close they are to the calculated sine function.
The first step towards this is to define how we might colour a point in relation to a value calculated for that point.

We will begin by defining a function getColor(int colorVal, int choice) that will allow us to plot a smooth gradient of colour. Values of the argument colorVal should be in the range 0 to 255, any values above or below this range will return the maximum or minimum colour defined by the function.

Two colouring options have been specified for this function. Which of these is used is determined by the value of the argument colorChoice - valid options for which are 1 and 2. Setting anything else will return 0, and the colour black, for all other values of the argument colorVal. In our main program colorChoice is set in the initial setup options, which can be found in the function setOptions().

Setting colorChoice to 1 gives us our simpler option - greyscale. This is easier to define since the argument colorVal is already in the range 0 to 255, we can simply set the red, green and blue values all to be equal to colorVal.

Setting colorChoice to 2 gives us our second option - a smooth colour shift from blue to red through green. To achieve this, the input range, 0 to 255, was divided into four equal sections. In each section two of the RGB values were kept constant whilst the other was increased or decreased to give a smooth transition.

For example, in the first section - colorVal between 0 and 63 - to get from blue to cyan:
  • Keep the red component of the colour as 0 and the blue value constant at 255
  • Then increase the amount of green proportional to the argument colorVal. We need to ensure the green value increases from 0 to 255 (approximately) based on colorVal, which ranges from 0 to 63; hence we multiply colorVal by 4.
Similarly in the other sections we subtract the start of the range from colorVal before multiplying by 4 to give a value between 0 and 255 that can be used to vary one of the colours red, green or blue.

//set everything to 0, will return black if colorVal outside range
int tempColor;
int redVal = 0;
int greenVal =0;
int blueVal =0;

//first section of colour scale
if ( colorVal >= 0 && colorVal <= 63){ tempColor = 4 * colorVal; redVal = 0; greenVal = tempColor; blueVal = 255; } //The other three sections are defined similarly, //they complete the shift to red return color(redVal,greenVal,blueVal);


With all four sections this gives us the colour scale in Figure 2.





Figure 2 colour scale

Next we define the function scaleValue(float val, float minVal, float maxVal) which converts the argument val to a float in the range 0 to 255 proportional to the arguments maxVal and minVal; such that val = maxVal returns 255 and val = minVal returns 0. We will use this result later in the function getColor().

To scale val we first need to ensure that the minimum value returned will be 0. This is achieved by subtracting the argument minVal - the minimum possible value that that val could take. Hence if val is greater than 0 it is reduced to 0, and conversely if val is less than 0 then it is increased to 0. This new adjusted value is adjVal.

Next we need to ensure that the maximum value returned is 255. In order to this we create a scale factor which we will multiply by adjVal to give us the required results.

We begin by adjusting the maximum value in the same way as before - subtracting the minimum value minVal. Then we divide 255 by this new adjusted maximum value adjMax to create a scale factor. This scale factor is multiplied by adjVal to produce a number in the range 0 to 255 proportional to the maximum and minimum values passed to scaleValue().

We can apply these two functions scaleValue() and getColorValue() to our original sine function to colour each point. The maximum at any given point will be red and the minimum will be blue. This is shown in Figure 3.

The additions to our original code are shown below

//set up initial variables as before

//add variables to hold color and scaled value used to set color
float colorValue;
color aColor;

//add three lines to change color of points as function is plotted
for(int x=0; x < y =" position" colorvalue =" scaleValue(y," acolor =" getColor(round(colorValue),">












Figure 3 colourful sine function with damping

Note that the minimum and maximum values change as the function is plotted, so that each peak and trough is plotted in the same colour. This is because the amplitude is passed to the scaleValue() function after each iteration so the damping is taken into account when determining the maximum and plotting each point.

No comments: