Showing posts with label processing. Show all posts
Showing posts with label processing. Show all posts

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.

Sine in action part 1

Posting the final draft is proving a little problematic, so I will be splitting it into several sections.

Chunk 54 – Sine in action

In this section we are going to develop a program that uses the sine function. Our program is designed in a modular way, with fairly self contained functions each handling different aspects of the program operation. Where functions could be reused elsewhere they are kept independent of the rest of the program by using arguments passed from other functions instead of relying on global variables.

Although this approach leads to some additional complexity, it is designed to allow code reuse and make future alterations simpler.

We will begin by discussing the individual functions that make up our program. At the end of this section we will combine these to give our main program. The full code is listed at the end; although where it clarifies explanations small excerpts have been used in the discussion.

The sine function

As we saw in section 53 the sine function is a trigonometric function which generates a periodic repeating wave.

The basic function takes the form

f(θ) = amplitude * sin( frequency * θ)

The maximum value of the sine function
f(θ) is equal to the amplitude, and the minimum value is equal to minus the amplitude. The function f(θ) varies smoothly between these values during the period of the wave.

The frequency affects the number of repetitions of the wave within the period 2 π radians; such that if frequency = 1 then the wave repeats once over the period and if
frequency = n then the wave repeats n times.

A damping variable can be used to decrease the amplitude over time such that the maximum and minimum values of the sine function tend towards to zero.

In the following example, the amplitude is decreased with each point plotted by multiplying the amplitude by the variable damping. The angle theta is increased from 0 to TWO_PI as x increases from 0 to width. To do this we define theta as a function of and width. We initialise theta to 0 and then with each iteration we add dTheta, where

dTheta = TWO_PI/width;

Additionally the variable frequency is set to 4 so the wave repeats four times within the period. This is shown in Figure 1.

size(600, 300);
background(0);
stroke(255);
strokeWeight(5);

float y = 0;
float theta = 0.0;
float amplitude = height/2 ;
float damping = 0.994;
float dTheta= TWO_PI/width;
float position = height/2;
float frequency = 4;
smooth();

for(int x=0; x <>
y = position + amplitude*sin(frequency*theta);
point (x, y);
amplitude *= damping;
theta += dTheta;
}













Figure 1 Sine function with damping