Saturday, 4 April 2009

Chunk 46 - Program Completed

The Chunk 46 program is shown running in the video below, it tends to run slower when the next image is more detailed. We could decrease the variable patsPerPic to speed it up a bit or adjust the framerate.

Chunk 46 - HeadLines from Rosie Wood on Vimeo.

Chunk 46 - Optional Modifications

This section is optional and we must decide if it is worth attempting to decipher another persons code our weite our own. The scenario is one which often crops up when writing a program. We have some code that someone else wrote, or code we ourselves wrote, that would add some desired quality to our application. It seems to fit the bill but when we copy and paste it into our own code we find that it isnt a perfect fit. We may decide it would be easier to just write our own code or we may feel that the code would save us a lot of time.




The code in this case, is contained in a for loop, in another program we wrote some time ago. It contains many new patterns and the images above only use a few of them. Study these images and decide whether you want to use them and modify THE CODE .
The finished code will not be available here and so you will have to buy the book or modify this code if you want to add the new patterns.
Tip: If your code slows down after making the changes, trace the code through the for loops and make sure you are clear about how many times a function is executing!

Friday, 3 April 2009

Ch46 - An Array of Difficult Choices

After careful consideration of how to implement the choices available for pattern 7 we decide to use an array to hold the available choices.
boolean [] segments={false,false,false,false,false,false,false,false};
If we allowed any choices at all for pattern 7 what would be the outcome? We decide to try this out and implement a function to use our array. We need to reset the arrays values to false when we start to draw a pattern 7 design. Then we must randomly decide which segments to draw.

void oops(){
resetSegs();
for(int n=0;n<8;n++){
if(round(random(1))==0){segments[n]=true;}
}
println(segments);
if(segments[0]==true){
line(0,height-y,y,y);}//oopsleft down
if(segments[1]==true){
line(width-x,0,x,x);}//oopsup right
if(segments[2]==true){
line(x,0,width-x,x);}//oopsup left
if(segments[3]==true){
line(width,y,y,height-y);}//oopsright down
if(segments[4]==true){
line(width,height-y,y,y);}//oopsrightup
if(segments[5]==true){
line(width-x,height,x,x);}//oopsdown left
if(segments[6]==true){
line(x,height,width-x,x);}//oopsdown right
if(segments[7]==true){
line(0,y,y,height-y);}//oopsleft up

}
void resetSegs(){
for(int n=0;n<segments.length;n++){>
segments[n]=false;
}
}
When we run our application with this function, every time our function executes, all the segments are drawn. On careful inspection, we realise that resetting the array and filling in the choices should not be within the function or the for loops. We move the offending code from the function to the start of the while loop:
while(count<patsperpic){
resetSegs();
for(int n=0;n<8;n++){
if(round(random(1))==0){segments[n]=true;}
}
changeColour();

An example of running our application with no limits on the choices for pattern 7, is as shown in the images above. We may decide that this is acceptable or not...
The patterns used in Chunk 46 include 4 different meshes, which we may feel don't merit a case statement each. If we moved this code to one case statement then we would have more patterns and less meshes.
Example Source Code with space for 2 new patterns
The next section is optional and involves adding new patterns from another program's for loop.

Thursday, 2 April 2009

Chunk 46 - Structure

In this section we will move our patterns into functions and decide how each function will control the symmetry of its own pattern.
We want to make our program as easy to manage as possible so we decide we will have a global variable that will control the amount of lines each statement will use to be drawn to the screen. As the size of the pixels is different vertically and horizontally we will use two for next loops to contain the pattern controlling.
Here is a list of the variables we might end up with:

int numLines=20;//changing this controls the amount of lines in a statement
int stepH=0; //used in for loop for vertical steps
int stepW=0; //used in for loop for horizontal steps
int n=0; //allows the value of n to be accessed from the functions
int x=0; //horizontal step
int y=0; // vertical step
int rannum=0; //a random number between 0 and 2
int design=1; //an integer to identify the case statement to execute
int count=0; //used to compare with the number of patterns per picture
int drawCount=0; //counts how many patterns have been displayed so far

Here is the basic structure of the application:

void setup(){
size(400, 400);
stepH=height/numLines;
stepW=width/numLines;
strokeWeight(1);
smooth();
frameRate(30);
}

void draw(){
patsPerPic=round(random(2,7));
background(0);
count=0;
n=0;
while(count&ltpatsperpic){>
changeColour();
rannum=round(random(2));
design=round(random(2));


for(x=0;x <width+1;x=x+stepw){
for y=0;y<height+1;y+=stepH){">



switch(design){
case 0: function0(); break;
case 1: function1(); break;
case 2:function2();break;
} } }//end of fors
count++;
}//end of while
drawCount++;
}//end of draw

void changeColour(){
stroke(random(255),random(255),random(255),random(255));
}

void function0(){
line(whatever);
}
void function1(){
line(whatever);
}
void function2(){
line(whatever);
}

Lets look at one of our functions and how the value of rannum decides which patterns are drawn.

void bigArches(){
//rannum=0;
if(rannum==1||rannum==0){
line(x,0,width,x);//large mesh ur
line(0,y,y,width);}
if(rannum==2||rannum==0){
line(0,height-y,y,0);//large mesh u l
line(width,height-y,y,height);}
}

The way we have designed this function, allows 3 choices. If the value of rannum is zero, it can be seen that both if statements are executed. A value of 1 or two only executes one of the if statements. If we wanted the arches to be totally symmetrical, we could set the value of rannum to zero within the function.
If we are working on a function, then we can replace the design variable in the switch, with the number of the case statement we are working on.
e.g.
switch(3){
To add a function to the basic structure we would add the function, give it a case statement and increase the size of the random number used to choose the design. If a pattern only uses one statement there is little benefit in moving it to a function. How we decide the options availablr for each pattern is a matter of personal taste. Most of the functions will have a structure similar to the bigArches function above but you may decide that a pattern is too trivial to be shown on its own and so give it no options e.g.
void inwards(){
line(0,0,height-y,y);//inwards l d
line(width,height,y,height-y);//inwards r u
line(0,height,y,y);//inwards l u
line(width,0,y,y);//inwards r d
}
This means that when this design is chosen it will always show the four statements in its pattern,
Some statenents in a pattern could be shown on their own, in a pair or as one of four. This gives 7 choices and this is easy to implemrnt by choosing a random number in the function. e.g.
void butterfly(){
int rannum=round(random(6));
if(rannum==1||rannum==5||rannum==0)
line(x,height-y,width-x,0);
if(rannum==2||rannum==5||rannum==0)
line(x,y,width-x,height);
if(rannum==3||rannum==6||rannum==0)
line(width,width-y,x,y);
if(rannum==4||rannum==6||rannum==0)
line(0,y,x,height-y);
}
However, you may decide that you dont like the symmetry of the designs produced when only one statement of the four is used in a pattern and just use the rannum variable to control the oppositely located pairs of statements.
void butterfly(){
if(rannum==1||rannum==0){
line(x,height-y,width-x,0);
line(x,y,width-x,height);}
if(rannum==2||rannum2==0){
line(width,width-y,x,y);//butterfly r
line(0,y,x,height-y);}}
As was demonstrated in the last section the amount of choices available when there are eight possible statements in a pattern is considerable. When implementing such a design, we may decide to simplify it, if it is not bringing anything worthwhile to the program. e.g.
void triangle3(){
if(rannum==1||rannum==0){
line(0,0,y,height);//ray uld
line(0,0,width,height-y);//ray ulr
line(width-x,0,width,height);//ray d r u
line(0,y,width,height);//ray d r l
}
if(rannum==2||rannum==0){
line(width,0,0,height-y);//ray u r l
line(width,0,height-y,height);//ray u r d
line(0,height,width-x,0);// dl u
line(0,height,width,height-y);//ray d l r
}}

On the other hand we may decide that it is worth the added complexity if it brings some quality to our application.
Implementing pattern 7 will warrant some careful consideration.

Wednesday, 1 April 2009

Chunk46 - Line Patterns

After much deliberation we come up with a motley collection of patterns which we will be re-factoring out to functions in the next section.
Our first pattern required 4 line statements to draw it and we placed these in our for loop. Looking at our collection of patterns we realise that some need a different amount of statements in order to be drawn and their symmetrical properties vary. We intend to make a randomised pattern generator, along the lines of Chunk16 but we have some decisions to make along the way, which will affect how the finished patterns will be generated.
One of our patterns requires only one statement and is totally symmetrical. Any function this pattern is used in will be vety simple as there are no choices to make. If you havent guessed this unique pattern is number 4.
Pattern 4 is symmetrical, horizontally, vertically and also diagonally. We have to decide, which symmetrical properties our sketch will be using. We could decide to make the symmetrical properties of our pattern vary and this would make it more complex to manage. Lets use the KISS principle to begin with...(Keep It Simple Stupid).
Pattern 4 required only one statement and two of our patterns are only a little more complex having only 2 possible statements in their code. In our example pattern numbers 5, 6 and 11 have only 2 possible statements.
Lets look at their symmetry:
Pattern 5:


This pattern has 3 possible display options, we can display both images together which forms a grid and is totally symmetrical or we can use one of the images alone, to produce horizontally or vertically, symmetrical stripes.
Pattern 6:


Again we can choose vertical, horizontal or total symmetry.
Pattern 11:

Pattern 11 covers the whole display area with one statement, which has diagonal and either horizonal or vertical symmetry depending on which one of the two statements in the set is used. Using both statements acheives total symmetry.

Each pattern in our next group requires 4 statements to be drawn and has other display options. Lets look at them one by one:
Pattern 2:


Our options are beginning to get more complicated here. We can display each single pattern on its own but this would be assymetrical and would not fill the display screen. The diagonally opposite patterns would be symmetrical on the diagonal axes and would give us another two choices or we could use all the statements, to produce a totally symmetrical pattern which could cover most of all previous patterns in one "coat".
Pattern 3:


This pattern is similar to pattern 2, in that we have 3 symmetrically possible choices but it would probably allow any underlying patterns to show through.
Pattern 8:


Pattern 8 covers the screen in one statement but it is not very symmetrical, having a semi symmetry on one diagonal axis. Using two statements with diagonal symmetry might be a better option or using all four statements in the set gives us a totally symmetrical pattern.
Pattern 9:


I call this pattern the butterfly and although it is an attractive pattern its symmetry could be hard to explain and implement. Depending on the statements chosen it can have total, horizontal, vertical or diagonal symmetry. As in pattern 8 it covers the screen in one statement and each statement has horizontal or vertical symmetry on its own.
Pattern 10:


This is another simple pattern which presents no problems.

Our final two patterns have 8 statements in each set, which further complicates things by allowing more options for symmetrical displays:
Pattern 12:




If we pick out some combinations of statements from the set of Pattern 12, we could find the above patterns but we have probably missed some. We will not discuss the symmetry of pattern 12 here but we will have to study it again when we move it to a function.
Pattern 7:
Like the preceding pattern there are 8 statements in this set. Although we are not going to study Set Theory in this chapter, it may help give us some insight to help us manage the options available. A set has a number of subsets equal to 2 to the power of the number of its elements. In the case of pattern 7 this is simply 2^8. This gives us 2x2x2x2x2x2x2x2 or 256 possible combinations, including the empty set, which we don't want, as it would just result in an empty screen. We could list this set formally as:
Pattern8={{1},{2},{3},{4},{5},{6},{7},{8},{1,2},{1,3},
{1,4},{1.5},{1,6},{1,7},{1,8},{2,3},{2,4},{2,5},{2,6},{2,7},
{2,8},{3,4},{3,5},{3,6},{3,7},{3,8},{4,5},{4,6},{4,7},{4,8},
{5,6},{5,7},{5,8},{6,7},{6,8},{7,8},{1,2,3},{1,2,4},{1,2,5},{1,2,6}
,{1,2,7},{1,2,8},{1,3,4},{1,3,5},{1,3,6},{1,3,7},{1,3,8},{1,4,5},{1,4,6},{1,4,7}
,{1,4,8},{1,5,6},{1,5,7},{1,5,8},{1,6,7},{1,6,8},{1,7,8},{2,3,4},{2,3,5},{2,3,6},{2,3,7},{2,3,8},{2,4,5),{2,4,6},{2,4,7},{2,4,8},{2,5,6},{2,5,7},{2,5,8},{2,6,7},{2,6,8},{2,7,8}{3,4,5},{3,4,6},{3,4,7},{3,4,8},{3,5,6},{3,5,7},{3,5,8},{3,6,7},{3,6,8},{3,7,8},{4,5,6}{4,5,7},{4,5,8},{4,6,7},{4,6,8},{4,7,8}{5,6,7}{5,6,8},{5,7,8}{6,7,8},

{1,2,3,4},{1,2,3,5},{1,2,3,6}
,{1,2,3,7},{1,2,3,8}{1,2,4,5},{1,2,4,6},{1247},{1,2,4,8},{1,2,5,6},{1,2,5,7},{1,2,5,8}{1,2,6,7}

,{1,2,6.8},{1,2,7,8}{1,3,4,5},{1,3,4,6},{1,3,4,7},{1,3,4,8},{1,3,5,6},{1,3,5,7},{1,3,5,8},{1,3,6,7}

,{1,3,6,8},{1,3,7,8},{1,4,5,6},{1,4,5,7},{1,4,5,8},{1,5,6,7},{1,5,6,8},{1,5,7,8},{1,6,7,8},{2,3,4,5},{2,3,4,6}

,{2,3,4,7},{2,3,4,8},{2,3,5,6},{2,3,5,7},{2,3,5,8},{2,3,6,7},{2,3,6,8},{2,3,7,8},{2,4,5,6},{2,4,5,7}

,{2,4,5,8},{2,5,6,7},{2,5,6,8},{2,5,7,8},{2,6,7,8},{3,4,5,6},{3,4,5,7},{3,4,5,8},{3,4,6,7},{3,4,6,8},{3,5,6,7},{3,5,6,8},{3,5,7,8},{3,6,7,8},{4,5,6,7},

{1,2,3,4,5},{12346}
,{1,2,3,4,7},{1,2,3,4,8},{1,2,3,5,6},{1,2,3,5,7},{1,2,3,5,8},{1,2,3,6,7},{1,2,3,6,8},{1,2,3,7,8},{1,3,4,5,6},{1,3,4,5,7},{1,3,4,5,8},{1,3,4,6,7},{1,3,4,6,8},{1,3,4,7,8},{1,3,5,6,7},{1,3,5,6,8},{1,3,5,7,8},{1,3,6,7,8},{1,4,5,6,7},{1,4,5,6,8},{1,4,5,7,8},{1,4,6,7,8},{1,5,6,7,8}
,{2,3,4,5,6},{2,3,4,5,7},{2,3,4,5,8},{2,3,4,6,7},{2,3,4,6,8},{2,3,4,7,8},{2,3,5,6,7},{2,3,5,6,8},{2,3,5,7,8},{2,3,6,7,8},{2,4,5,6,7},{2,4,5,6,8},{2,4,5,7,8},{2,5,6,7,8},{3,4,5,6,7},{3,4,5,6,8},{3,4,5,7,8},{4,5,6,7,8}


,{1,2,3,4,5,6},{1,2,3,4,5,7},{1,2,3,4,5,8},{1,2,3,4,6,7},{1,2,3,4,6,8}
,{1,2,3,4,7,8},{1,3,4,5,6,7},{1,3,4,5,6,8},{1,3,4,5,7,8},{1,3,4,6,7,8},{1,3,5,6,7,8}




{1,2,3,4,5,6,7},{1,2,3,4,5,6,8},{1,2,3,4,5,7,8},{1,2,3,4,6,7,8},{1,2,3,5,6,7,8},{1,2,4,5,6,7,8},{1,3,4,5,6,7,8},{2,3,4,5,6,7,8},{1,2,3,4,5,6,7,8}}
tHIS IS A WORK IN PROGRESS!
Sometimes we end up wishing we hadnt started something and this is one of these times! A couple of hours later and still over 50 combinations short!

Anyway to continue.....
Pattern 7:
We will stop there with pattern 7 but as can be seen, there are many decisions to be made over which combination of pattern 7 statements we will allow, maybe it would be easier to choose the ones we wont allow! Our next task is to place each pattern in its own function and control its drawing from a for loop within the draw method.

Tuesday, 31 March 2009

Chunk 46 - HeadLines

I have been given the go ahead to do chunk 46, which will be along the lines of lines. There isnt much on the subject of maths that my mind retains for long but one of the very few lessons that stuck was in Geometry and the subject was lines. I suppose that everyone was taught this lesson, and how by placing lines correctly on a grid produces curves. To me it is equivalent to the chemistry lesson where mixing 2 clear liquids produced a coloured one. It was on the strength of this long remembered concept, I decided to do Chunk 46.
To jog everyones memory we will repeat the lesson by placing lines along the x and y axes of a grid but we will be using Processing instead of squared paper and a sharp pencil.

int n=0;

void setup(){

size(400,400);
strokeWeight(1);
background(255);

}

void draw(){
line(0,n,n+10,height);
n+=10;
delay(200);
if(n>height){
n=0;
}}


Using Processing it has not taken us long to produce this sketch and not a smudge in sight! We even slowed it down by a fifth of a second, to help demonstrate what was happening!
Now we have produced our sketch, we decide to repeat the exercise, in the four corners of our screen. Unfortunately we dont have a calculator to work this out for us and we have to calculate the beginning and ending of each line in the virtual graph.
line(0,n,n+10,height);
Fortunately we have a pattern to guide us, in the code we used to create the first sketch. We can see that the pattern starts at zero across and a variable n, which increases by ten each time the draw method is exited and reexecuted. The end coordinate is the value of n+10 and is always the height of the screen downwards. To make our next pattern at the bottom right corner we know the first coordinate should start at the width of the screen across and have n pixels down. On each iteration, the point should have a variable number across and a fixed value equal to the height of the screen. If we are careful not to hard code any of the integers used to draw our sketch, this will mean our code can run in any size of window.
The way we coded the pattern sketch was ok to demonstrate the lines being drawn but we shall place the code in a for loop now, as we are using steps to increment the value of the gaps between the lines.
Try to calculate the statements needed to draw the other three patterns. The mathematically minded can use their free time to come up with some other patterns to use in their program and those whose mathematics are more artistic will come up with loads of new patterns as they try to work out the numbers.
Add a function to change the stroke colour each time the draw loop repeats. The finished sketch should look like the illustration and hopefully you will have thought up some new patterns, which we shall use in the next section.