13
57 Punto 12 – Funciones de usuario Introducción En Processing cualquier usuario puede programar sus propias funciones. Llamamos a esto función de usuario. Una función es un módulo de programación autocontenido. Las funciones de usuario hacen más conciso el código redundante al extraer los elementos comunes e incluirlos en bloques de código para que puedan ejecutarse tantas veces se quiera dentro del programa. Esto permite una lectura más fácil del código y reduce las probabilidades de error al actualizar el código. Las funciones generalmente tienen parámetros que definen sus acciones. Las funciones pueden operar de forma diferente dependiendo del número de parámetros usados. Una función puede ser imaginada como una caja con mecanismos dentro que actúan sobre los datos ingresados y devuelven un resultado. Convencionalmente posee una o varias entradas, un bloque de código que procesa dichas entradas, y finalmente una salida: Algunos ejemplos de diagramas de función de usuario: Abstracciones En términos informáticos, se llama abstracción al proceso que permite esconder los detalles de realización del código y concentrarnos en las operaciones resueltas. En realidad todas las funciones Introducción a Processing v1.5+ Docente: Raúl Lacabanne

Intro Processing v1.5 - 12 - Raúl lacabanne

Embed Size (px)

DESCRIPTION

Intro Processing v1.5 - 12 - Raúl lacabanne

Citation preview

Page 1: Intro Processing v1.5 - 12 - Raúl lacabanne

57

Punto 12 – Funciones de usuario

Introducción

En Processing cualquier usuario puede programar sus propias funciones. Llamamos a esto función de usuario. Una función es un módulo de programación autocontenido. Las funciones de usuario hacen más conciso el código redundante al extraer los elementos comunes e incluirlos en bloques de código para que puedan ejecutarse tantas veces se quiera dentro del programa. Esto permite una lectura más fácil del código y reduce las probabilidades de error al actualizar el código. Las funciones generalmente tienen parámetros que definen sus acciones. Las funciones pueden operar de forma diferente dependiendo del número de parámetros usados.

Una función puede ser imaginada como una caja con mecanismos dentro que actúan sobre los datos ingresados y devuelven un resultado.Convencionalmente posee una o varias entradas, un bloque de código que procesa dichas entradas, y finalmente una salida:

Algunos ejemplos de diagramas de función de usuario:

Abstracciones

En términos informáticos, se llama abstracción al proceso que permite esconder los detalles de realización del código y concentrarnos en las operaciones resueltas. En realidad todas las funciones

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 2: Intro Processing v1.5 - 12 - Raúl lacabanne

58

de sistema que hemos visto hasta el momento son, técnicamente, abstracciones: los autores han escondido los detalles de implementación para que el programador se concentre en los resultados.Cuando construimos funciones estas podrán devolver un resultado o no. Depende evidentemente de qué queramos hacer con ella. Pero en el caso de optar por la no devolución de un resultado deberemos comenzar por construir el bloque con la palabra clave void. Es por esto que todos los ejemplos que veremos a continuación comienzan a construirse con dicha palabra clave.

Ejemplo 1:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// esta función será llamada automáticamente por Processing// cuando el programa se ejecutevoid setup() {    size(200, 200);  // configura el tamaño de pantalla } 

// esta función también será llamada automáticamente luego de setup()void draw() {   rect(100, 30, 90, 160); // crea un rectángulo} 

// El "flujo de ejecución" será el siguiente: // 1) setup() // 2) size(200, 200) // 3) draw() // 4) rect(10, 10, 90, 160); 

Ejemplo 2:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

void setup() {  size(200, 200);   background(255);  // establece el color de fondo en blanco } 

void draw() {  // cuatro llamadas a la función definida por el usuario cross() 

  // el "origen del sistema de coordenadas" por defecto se encuentra  // en la esquina superior izquierda de la pantalla  cruz();      // esquina superior izquierda de la cruz en 0,0

  // el "origen del sistema de coordenadas" se mueve 50 px  // a la derecha y 50 px abajo  translate(50, 50);   cruz();      // esquina superior izquierda de la cruz en 50,50

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 3: Intro Processing v1.5 - 12 - Raúl lacabanne

59

  // el "origen del sistema de coordenadas" se mueve otros 50 px  // a la derecha y 50 px abajo  translate(50, 50);    cruz();      // esquina superior izquierda de la cruz en 100,100 

  // el "origen del sistema de coordenadas" se mueve otros 50 px  // a la derecha y 50 px abajo  translate(50, 50);    cruz();      // esquina superior izquierda de la cruz en 150,150 } 

// nuestra función definida por el usuario, que podemos nombrarla// como queramos siempre y cuando no se superponga con funciones// de sistema preestablecidas.void cruz() {    noStroke();   fill(255, 0, 0);  // rojo  rect(0, 10, 30, 10);   rect(10, 0, 10, 30); }

Ejemplo 3:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// cuando dibujamos usando funciones es importante poder tener// la posibilidad de dibujar una forma desde el centro... void setup() {  size(200, 200);   background(255); }  void draw() {  cruz();      // esquina superior izquierda de la cruz en 0,0

  // el "origen del sistema de coordenadas" se mueve 50 px  // a la derecha y 50 px abajo  translate(50, 50);   cruz();      // esquina superior izquierda de la cruz en 50,50

  // el "origen del sistema de coordenadas" se mueve otros 50 px  // a la derecha y 50 px abajo  translate(50, 50);    cruz();      // esquina superior izquierda de la cruz en 100,100 

  // el "origen del sistema de coordenadas" se mueve otros 50 px  // a la derecha y 50 px abajo  translate(50, 50);    cruz();      // esquina superior izquierda de la cruz en 150,150} 

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 4: Intro Processing v1.5 - 12 - Raúl lacabanne

60

 void cruz() {  noStroke();   fill(255, 0, 0);   rectMode(CENTER);  // los rectángulos serán dibujados desde el centro   rect(0, 0, 30, 10);   rect(0, 0, 10, 30); }

Ejemplo 4:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// cuando creamos funciones personalizadas es posible agregar// un número arbitrario de "parámetros" que actuarán como// variables dentro del bloque de la función

void setup() {  size(200, 200);   background(255); } 

void draw() {  // cuando llamamos a nuestra función, estamos "pasando"  // 2 parámetros que afectarán la posición de la cruz 

  cruz(0, 0);     // el centro de la cruz se encuentra en 0,0   cruz(50, 50);   // el centro de la cruz se encuentra en 50,50   cruz(100, 100); // el centro de la cruz se encuentra en 100,100   cruz(150, 150); // el centro de la cruz se encuentra en 150,150 } 

void cruz(float ejeX, float ejeY) {// estamos usando dos parámetros ejeX y ejeY (los nombramos a voluntad// sin repetir otras variables de sistema o ya creados)   noStroke();   fill(255, 0, 0);   rectMode(CENTER); 

  // ejeX y ejeY están actuando como variables y han sido  // declaradas por fuera del bloque de la función   rect(ejeX, ejeY, 30, 10);       rect(ejeX, ejeY, 10, 30); } 

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 5: Intro Processing v1.5 - 12 - Raúl lacabanne

61

Ejemplo 5:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// introducción de parámetros adicionales void setup() {  size(200, 200);   background(255); }  void draw() {  // definición de variables que contienen información de color   color rojo = color(255, 0, 0);   color azul = color(51, 153, 255);   color gris = color(128, 128, 128);   color verde = color(153, 255, 51);    // estamos pasando un tercer parámetro que afectará el tamaño de la cruz   // y un cuarto parámetro que permitirá en control de color de la cruz   cruz(0, 0, 1, rojo);   cruz(50, 50, 3, azul);   cruz(100, 100, 0.5, gris);   cruz(150, 150, 5.5, verde); }  void cruz(float x, float y, float tamanio, color colorCruz) {// 2 nuevos parámetros han sido agregados a la función   noStroke();   fill(colorCruz);  // esto controla el color de la cruz  rectMode(CENTER);    rect(x, y, 30 * tamanio, 10 * tamanio);       rect(x, y, 10 * tamanio, 30 * tamanio); } 

Ejemplo 6:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// ¡cuando se programa es posible alcanzar los mismos resultados utilizando diferentes acercamientos! void setup() {  size(200, 200);   background(255); }  void draw() {

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 6: Intro Processing v1.5 - 12 - Raúl lacabanne

62

  fill(255, 0, 0);     // rojo  cruz(0, 0, 1);    fill(51, 153, 255);  // azul   cruz(50, 50, 3);    fill(128, 128, 128); // gris   cruz(100, 100, 0.5);    fill(153, 255, 51);  // verde   cruz(150, 150, 5.5); }  void cruz(float x, float y, float tamanio) {  noStroke();   rectMode(CENTER);    rect(x, y, 30 * tamanio, 10 * tamanio);       rect(x, y, 10 * tamanio, 30 * tamanio); } 

Ejemplo 7:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// usar funciones que usan otras funciones... // primero hagamos dos figuras diferentes y examinémoslas por separado void setup() {  size(200, 200);   background(255);   fill(0, 0, 0);  // todas las figuras con relleno negro}  void draw() {  burbujas(50, 100);   tubo(150, 100); }  void tubo(float x, float y) {  noStroke();   rectMode(CENTER);   ellipseMode(RADIUS);   rect(x, y, 40, 100);   rect(x, y ­ 50, 60, 10);   ellipse(x, y + 50, 20, 20); }  void burbujas(float x, float y) {  noStroke();   ellipseMode(RADIUS);   ellipse(x + 4, y ­ 24, 10, 10);   ellipse(x ­ 4, y, 9, 9); 

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 7: Intro Processing v1.5 - 12 - Raúl lacabanne

63

  ellipse(x + 4, y + 24, 8, 8);   ellipse(x ­ 4, y + 48, 7, 7); } 

Ejemplo 8:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// usar funciones que usan otras funciones... // ahora hagamos una función que usa juntas y de manera compuesta// nuestras dos funciones anteriores void setup() {  size(200, 200);   background(255); }  void draw() {  peligro(50, 100);   peligro(75, 80);   peligro(100, 100);   peligro(125, 120);   peligro(150, 100); }  void peligro(float x, float y) {  fill(0, 0, 0);  // negro  tubo(x, y);    fill(255, 255, 255);  // blanco  burbujas(x, y); } 

void tubo(float x, float y) {  noStroke();   rectMode(DIAMETER);   ellipseMode(RADIUS);    rect(x, y, 40, 100);   rect(x, y ­ 50, 60, 10);   ellipse(x, y + 50, 20, 20); }  void burbujas(float x, float y) {  noStroke();   ellipseMode(RADIUS);    ellipse(x + 4, y ­ 24, 10, 10);   ellipse(x ­ 4, y, 9, 9);   ellipse(x + 4, y + 24, 8, 8);   ellipse(x ­ 4, y + 48, 7, 7); } 

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 8: Intro Processing v1.5 - 12 - Raúl lacabanne

64

Ejemplo 9:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// usar funciones que usan otras funciones... 

// generar una función que utiliza nuestras 2 piezas compuestas juntas// más la introducción de escalado (usando un parámetro adicional) 

void setup() {  size(200, 200);   background(255); } 

void draw() {  peligro(50, 100, 13);  // más grande  peligro(150, 100, 5);  // más pequeño} 

void peligro(float x, float y, float tamanio) {  fill(0, 0, 0);  // negro  tubo(x, y, tamanio); 

  fill(255, 255, 255);  // blanco   burbujas(x, y, tamanio); } 

void tubo(float x, float y, float tamanio) {  noStroke();   rectMode(DIAMETER);   ellipseMode(RADIUS); 

  rect(x, y, 4 * tamanio, 10 * tamanio);   rect(x, y ­ 5 * tamanio, 6 * tamanio, 1 * tamanio);   ellipse(x, y + 5 * tamanio, 2 * tamanio, 2 * tamanio); } 

void burbujas(float x, float y, float tamanio) {  noStroke();   ellipseMode(RADIUS); 

  ellipse(x + 0.4 * tamanio, y ­ 2.4 * tamanio, 1 * tamanio, 1 * tamanio);   ellipse(x ­ 0.4 * tamanio, y, 0.9 * tamanio, 0.9 * tamanio);   ellipse(x + 0.4 * tamanio, y + 2.4 * tamanio, 0.8 * tamanio, 0.8 * tamanio);   ellipse(x ­ 0.4 * tamanio, y + 4.8 * tamanio, 0.7 * tamanio, 0.7 * tamanio); } 

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 9: Intro Processing v1.5 - 12 - Raúl lacabanne

65

Ejemplo 10:// Programación basada en primitivas// usando funciones personalizadas// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// usar funciones que usan otras funciones... // generar una función que utiliza nuestras 2 piezas compuestas juntas// más la introducción de escalado basado en una matriz de transformación void setup() {  size(200, 200);   background(255); }  void draw() {  peligro(50, 100, 1.3);   peligro(150, 100, 0.5); }  void peligro(float x, float y, float sz) {  fill(0, 0, 0);  // negro  pushMatrix();   translate(x, y);   scale(sz);   tubo();   popMatrix();    fill(255, 255, 255);  // blanco  pushMatrix();   translate(x, y);   scale(sz);   burbujas();   popMatrix(); } 

void tubo() {  noStroke();   rectMode(DIAMETER);   ellipseMode(RADIUS);    rect(0, 0, 40, 100);   rect(0, ­ 50, 60, 10);   ellipse(0, 50, 20, 20); }  void burbujas() {  noStroke();   ellipseMode(RADIUS);    ellipse(4, ­ 24, 10, 10);   ellipse(­4, 0, 9, 9);   ellipse(4, 24, 8, 8);   ellipse(­4, 48, 7, 7); } 

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 10: Intro Processing v1.5 - 12 - Raúl lacabanne

66

Ejemplo 11:// Programación basada en primitivas// usando funciones personalizadas o funciones definidas por el usuario// Autor: Ariel Malka | www.chronotext.org// URL: http://goo.gl/1IMAhJ// Traducción: Raúl Lacabanne ­ 2009

// usar funciones que usan otras funciones... 

// generar una función que utiliza nuestras 2 piezas compuestas juntas// más la introducción de escalado basado en una matriz de transformación

void setup() {   size(200, 200);   background(255); } 

void draw() {   peligro(50, 100, 1.3);   peligro(150, 100, 0.5); } 

void peligro(float x, float y, float tamanio) {   fill(255, 0, 0);  // rojo  pushMatrix();   translate(x, y);   scale(tamanio);   tubo();   fill(255, 255, 255);   // blanco  burbujas();  popMatrix(); } 

void tubo() {   noStroke();   rectMode(DIAMETER);   ellipseMode(RADIUS); 

  rect(0, 0, 40, 100);   rect(0, ­ 50, 60, 10);   ellipse(0, 50, 20, 20); } 

void burbujas() {   noStroke();   ellipseMode(RADIUS); 

  ellipse(4, ­ 24, 10, 10);   ellipse(­4, 0, 9, 9);   ellipse(4, 24, 8, 8);   ellipse(­4, 48, 7, 7); } 

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 11: Intro Processing v1.5 - 12 - Raúl lacabanne

67

Ejemplo 12:void setup(){  size(640, 360);  background(102);  smooth();}

void draw() {  elipseVariable(mouseX, mouseY, pmouseX, pmouseY);}

// elipseVariable() calcula la velocidad del ratón.// Si el ratón se mueve lentamente: dibuja una elipse pequeña,// si el ratón se mueve rápidamente: dibuja una elipse mayor si

void elipseVariable(int x, int y, int px, int py) {  float speed = abs(x­px) + abs(y­py);  stroke(speed);  ellipse(x, y, speed, speed);}

Valor de retorno

Hasta ahora, en todos los ejemplos, hemos visto que la salida de una función que dibuja primitivas se ha realizado en el área de representación. Sin embargo a veces necesitaremos que la salida de una función sea un número u otro tipo de dato. La salida de una función se llama valor de retorno.Se espera que todas las funciones regresen un valor, tal como un entero o un decimal. Si la función no regresa un valor, se utiliza la palabra especial void. El tipo de dato regresado por una función se encuentra a la izquierda del nombre de función.El comando clave return es usado para salir de una función y regresar al lugar desde el cual fue llamado. Cuando una función regresa un valor, return es usado para especificar qué valor debe ser regresado.La instrucción que incluye return es generalmente la última de una función, ya que la misma finaliza inmediatamente después de un retorno. Ya hemos usado funciones que devuelven valores: por ej.: random() regresa un decimal, color() regresa un tipo de dato de color, etc.Si una función regresa un valor, dicha función casi siempre aparece a la derecha de un operador de asignación o como parte de una expresión mayor. Una función que no regresa un valor es frecuentemente usada como una instrucción completa.Las funciones no están limitadas a regresar números: pueden regresar boolean, String, PImage o cualquier otro tipo de dato.Para escribir una función de usuario que regrese un valor, reemplace void con el tipo de dato que necesite regresar, e incluya dentro de la función la palabra clave return seguido de la variable que contenga el valor que desee regresar para habilitar la salida del mismo.

A continuación veremos un ejemplo:void setup() {  size(100, 100);  float f = promedio(12.0, 6.0); // Asigna 9.0 a f  println(f);}

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 12: Intro Processing v1.5 - 12 - Raúl lacabanne

68

float promedio(float num1, float num2) {  float av = (num1 + num2) / 2.0;  return av;}

Sobrecarga de funciones (Function overloading)

Se llama sobrecarga de funciones al procedimiento de crear diferentes versiones de una misma función. Las distintas versiones pueden compartir el mismo nombre de función siempre y cuando tengan diferentes números de parámetros o tipos de datos de los mismos. Es decir, un programa puede tener dos funciones con el mismo número de parámetros, pero sólo si el tipo de dato de uno de sus parámetros es diferente.Processing identifica automáticamente qué versión de función debe ejecutar al comparar el número y el tipo de dato de sus parámetros.

Veamos el próximo ejemplo:void setup() {  size(100, 100);  smooth();}

void draw() {  dibujoX(255); // Ejecuta primer dibujoX()  dibujoX(5.5); // Ejecuta segundo dibujoX()  dibujoX(0, 2, 44, 48, 36); // Ejecuta tercer dibujoX()}

// dibujoX con el valor de gris determinado por el parámetrovoid dibujoX(int gris) {  stroke(gris);  strokeWeight(20);  line(0, 5, 60, 65);  line(60, 5, 0, 65);}

// dibujoX negro con el valor ancho de contorno determinado por el parámetrovoid dibujoX(float ancho) {  stroke(0);  strokeWeight(ancho);  line(0, 5, 60, 65);  line(60, 5, 0, 65);}

// dibujoX con la posición , el valor de gris, tamaño y el ancho de// contorno determinados por sus correspondientes parámetrosvoid dibujoX(int gris, int ancho, int x, int y, int s) {  stroke(gris);  strokeWeight(ancho);  line(x, y, x+s, y+s);  line(x+s, y, x, y+s);}

Introducción a Processing v1.5+  Docente: Raúl Lacabanne

Page 13: Intro Processing v1.5 - 12 - Raúl lacabanne

69

Lectura recomendada

• Buioli, I. & Pérez Marín, J. "Processing: un lenguaje al alcance de todos", Autoedición, 2013, Unidad 19 "Estructuras: Funciones" (pag. 95).

• Reas, C. & Fry, B. "Processing: A Programming Handbook for Visual Designers and Artists”, MIT Press, 2007, Capítulo "Structure 3: Functions" (pag. 181).

Ejercicio 13

• Crear una forma animada autónoma que comunique la idea de "orden".• Utilizar funciones de usuario.• Comentar todas las instrucciones.

Ejercicio 14

• Crear una forma animada autónoma que comunique la idea de "caos".• Utilizar funciones de usuario.• Comentar todas las instrucciones.

Ejercicio 15

• Crear una forma interactiva que comunique la idea de "orden y caos".• Utilizar funciones de usuario.• Comentar todas las instrucciones.

Introducción a Processing v1.5+  Docente: Raúl Lacabanne