Functions

void() and return()

Functions in Processing are divided in two categories:

Functions that return data and functions that do not return data, instead do things.

void setup() {
  size(800, 500);
}

void draw() {
  background(map(mouseX, 0, width, 0, 255));
}

setup and draw do things and do not return data. But inside draw is the function map() which does return a value.

Syntax

Functions that do not return data are specified through void in front of the name of the function. Typical built-in functions are setup(), draw(), mousePressed() and keyPressed(). (For some more see this interaction tutorial.)

void setup() {
  size(800, 500);
  background(random(0, 256), random(0, 256), random(0,256));
  noCursor();
  noStroke();
}

void draw() {
  // map will return a value which can be stored inside a variable ...
  float r = map(mouseX, 0, width, 0, 255);
  fill(r, 100, 200);
  // ... or be inserted into a function directly
  circle(mouseX, mouseY, map(mouseY, 0, width, 8, 64)); 
}

void mousePressed() {
  clear();
  background(random(0, 256), random(0, 256), random(0,256));
}

Interactions like mousePressed() interrupt the regular draw()-loop. If the event (like the pressed mouse) is fired, the current iteration of the draw loop is finished first, then the code inside the block of code attached to the event is executed and after that the draw()-loop continues.

See this example for a custom void function.

While void() is set outside of a function, return is part of the inside of return-functions. A function we’ve used often is map(). We feed 5 values into the function and it returns one value. As a demonstration we’ll write our own map function which does exactly the same as the built-in function:

void setup() {
  size(800, 500);
  background(random(0, 256), random(0, 256), random(0,256));
  noCursor();
  noStroke();
}

void draw() {
  fill(map_val(mouseX, 0, width, 0, 255), 100, 200);
  circle(mouseX, mouseY, map_val(mouseY, 0, height, 8, 128)); 
}

/* Own map function.
It takes 5 arguments (input value + ranges)
and returns the mapped input as a float number.
The datatype of the return value has to be 
specified before the name of the function. */

float map_val(float val, float in_min, float in_max, float out_min, float out_max) {
  
  float new_val = (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  
  return new_val; 
}

A custom return-function starts with the data type that it will return, followed by a name of your choice (avoid keywords) and (). Input to the function is specified in here, also with data types. The inside of the function is put into {}. The function is finished with return. (It’s possible to have multiple return-statements inside a function, but the function will be exited after the first executed return.)

The name is an address to the function (like the names of variables) and through that functions are callable.

A custom map function

functions_custom_map


void setup() {
  size(800, 500);
  background(random(0, 256), random(0, 256), random(0,256));
  noCursor();
  noStroke();
}

void draw() {
  fill(map(mouseX, 0, width, 0, 255), 100, 200);
  circle(mouseX, mouseY, map_mid_max(mouseY, 0, height, 8, 128)); 
}


float map_mid_max(float val, float in_min, float in_max, float out_min, float out_max) {
  /* This map function maps out_max to the center
  in between in_min and in_max. The outer values
  are mapped to out_min.  
  Compute the absolute difference between the input (val)
  and the middle of in_min and in_max.
  Then use a regular map function with that value.
  (out_max and out_min are swapped in comparison to regular map(). */
  
  float center = in_max / 2;
  float new_val = abs(center - val);
  new_val = map(new_val, in_min, center, out_max, out_min);
  
  return new_val;
}

void mousePressed() {
  clear();
  background(random(0, 256), random(0, 256), random(0,256));
}

A custom random color function

functions_random_color


void setup() {
  size(800, 500);
  background(random_color(3));
  noCursor();
}

void draw() {
  stroke(random_color(3));
  fill(random_color(3));
  circle(mouseX, mouseY, 24);
}


color random_color(int channels) {
  /* Return a random color with
  the amount of channels specified
  through the input. */
  
  color c;
  
  if (channels == 1) {
    c = color(random(0, 256));
  }
  else if (channels == 3) {
    c = color(random(0, 256), random(0, 256), random(0, 256));
  }
  else {
    c = color(random(0, 256), random(0, 256), random(0, 256));
  }
  return c;
}


void mousePressed() {
  clear();
  background(random_color(3));
}

Why write custom functions?

  • Code is outside of the main loop

  • Code can be used multiple times inside the loop (or other parts of the program)

  • Code can be used in other programs as well