Tutorial 1.2:

a function for drawing a circle



Introduction
A function is a convenient way to organize your code, and allows you to build your own library of re-usable code. You should always document your functions clearly so they can be easily re-used by you or by someone else. A function is a block of code, contained within curly brackets, that may receive some information when called (parameters) and may (or may not) return a value or values when it closes. Functions that return nothing are referred to as 'void' in Processing and Java (the programming language in which Processing itself is written).

Example
In this example we'll write a function that draws a circle.



We'll start as we always do by providing some information about the sketch:

/*
November 2014
CD 1
Mark Meagher and Adam Park
makeCircle function
*/

Following this we can declare any variables that we're going to use in the sketch. It's useful to define at the beginning of the sketch any variables that you expect to use repeatedly in different parts of your code, and any variables that you want to be able to change easily while debugging and testing. Variables defined at the beginning of your sketch, before the setup(), are called Global Variables because their value is stored for use throughout the sketch. In this case we'll declare the x-position and y-position of our circle and the color of its fill as a greyscale value:

int myXPosition; //X position of the circle
int myYPosition; //Y position of the circle
int myGreyscale = 200; //colour of the circle

We'll then specify the initial properties of the Processing environment using the void setup() function. Note that setup() is a reserved function in Processing that is automatically called once each time your sketch starts. Unlike setup() and draw(), most Processing function are not called automatically and must be called explicitly in your code. The setup() function is void because it returns nothing when it completes. Note that like all functions, this one consists of a name followed by a pair of closed parentheses and an open curly bracket:

void setup() {
  size(400, 400);  
  background(240);
  frameRate(24); //this sets the framerate to 24/second
  smooth(); //smooth (anti-aliased) edges
  myXPosition = width/2;
  myYPosition = height/2;
  stroke(0); //Sets the color used to draw lines and borders around shapes
  strokeWeight(1);
  noFill();
  print("X-position is "+myXPosition);
}

Note that the values for strokeWeight and stroke will remain in effect as long as the sketch runs, or until they are changed in another part of the code.



The next step is to define our function. A function definition consists of the name of the function, followed by a list of parameters in parentheses, followed by the code that gets executed when the function is called in curly brackets. This function is void because it doesn't return anything: it creates a circle and then terminates.

void makeCircle(int myRadius, int myColor, int myX, int myY) {
   stroke (myColor,100); //set the alpha value to create a 'layered' appearance as the circle moves
   ellipse(myX, myY, myRadius, myRadius);
}

We've defined four parameters: each of which is a variable that contains a numeric value or integer which is why we've set the type of these variables as 'int'. These variables are then used when we create the circle using the 'ellipse' function. In the case of our three global variables note that we've used a different variable name to indicate that the variables within the function are local variables - their value is forgotten once the function has terminated.



We can then call our new function in the draw() function, using the current value of the global variables myXPosition and myYPosition to determine where on our stage the circle is drawn, and the value of myGreyscale to determine its color.

void draw() {
   makeCircle(diam, myGreyscale, myXPosition, myYPosition);   
}



What happens if you call the makeCircle function in setup() rather than draw()? Why?



What happens if you draw the background in draw() rather than setup()? Why?



We can use keyboard input in Processing to control our sketch as it's running using the built-in Processing function keyPressed() which is called automatically whenever any key is pressed: this is often a useful way to capture information about a particular version of a parametric model or to precisely control your sketch as it's running. In the following function, each a time a key is pressed we check what key has been pressed, and in certain cases we execute a line of code that changes the value of one of our global variables, myXPosition.



What is the effect of changing this global variable? Why ?



void keyPressed() {
  int mySpeed = 10;
  if (key == 'j') {
    myXPosition -= mySpeed;
  } else if (key == 'k') {
    myXPosition += mySpeed;
  }
}

Here's the full sketch:

/*
November 2014
 CD 1
 Mark Meagher and Adam Park
 makeCircle function
 */

int myXPosition; //X position of the circle
int myYPosition; //Y position of the circle
int myGreyscale = 200; //colour of the circle
int diam = 100;

void setup() {
  size(400, 400);
  background(240);
  frameRate(24);
  smooth();
  myXPosition = width/2;
  myYPosition = height/2;
  stroke(0);
  strokeWeight(1);
  noFill();
  print("X-position is "+myXPosition);
}

/*
Function makeCircle
 parameters: circle radius, circle color, x-position, y-position
 purpose: creates a circle with the desired parameters
 */
void makeCircle(int myRadius, int myColor, int myX, int myY) {
  stroke (myColor,100); //set the alpha value to create a 'layered' appearance as the circle moves
  ellipse(myX, myY, myRadius, myRadius);
}

void draw() {
  makeCircle(diam, myGreyscale, myXPosition, myYPosition);
}


/*
checks whether the 'j' or 'k' key has been pressed
 if 'j': move the circle to the left
 if 'k': move the circle to the right
 */
void keyPressed() {
  int mySpeed = 10;
  if (key == 'j') {
    myXPosition -= mySpeed;
  } 
  else if (key == 'k') {
    myXPosition += mySpeed;
  }
}



Exercises:



1- Redraw the background in every frame, so previous positions of the circle are erased (this can be done by moving one line of code).

2- Change the keypressed function to allow diagonal motion if keys describing vertical and horizontal motion are pressed simultaneously.

3- Add a key that moves your circle in a circular (or elliptical) rotation around a center point.

4- Add another type of motion that you define on keypress.