PROCESSING


PROCESSING


ÍNDICE:

apuntes: TIC_II

1.-  "HOLA  MUNDO"
2.-   VARIABLES
3.-   OPERADORES Y COMPARADORES
4.-   ESTRUCTURA SECUENCIAL
5.-   FUNCIONES.
6.-   EL COLOR.
7.-   EL FORMATO DE COLOR.
8.-   LA ESTRUCTURA CONDICIONAL
9.-   FOR
10.- WHILE
11.- SETUP( ) y DRAW( )
12.- ALEATORIEDAD.
13.- IMÁGENES  DE FONDO.






1.- LA CONSOLA DE PROCESSING: "HOLA MUNDO"
La consola de proccesing se encuentra en negro  debajo del editor de texto. Sirve para ver lo que va haciendo  el programa y para poder ver algunos valores mediante el uso de la función  print( ).

print ("Hola Mundo"); //lo entrecomillado  se represta tal cual
print (5); // en la consola aparecerá  el valor 5
println (6); //aparece 6 en la misma línea pero ahora salta a otra nueva línea.


LOS COMENTARIOS EN PROCCESING:
// de línea

/*
multilínea
*/



2.- LOS DATOS Y LAS VARIABLES: 
Los datos son caracteres alfanuméricos o cualquier tipo de elmentos que el ordenador almacena  y modifica. Por ejemplo, el PC está constantemente recibiendo datos del ratón y del teclado. 
El hecho  de  guardar datos implica el uso de mayor  o menor uso  de la memoria del ordenador.
Tipos de datos: boolean (true/false, 1bit  de memoria), bye (-128 a 127, 8 bits de memoria), char (0..65535, 16 bits de memoria), int (32 bis de memoria en valores enteros), float (32bis en decimal), color (32bits en colores).

UNA VARIABLE es un contenedor  para guardar  estos datos.  Estas variables permiten reutilar estos datos cada vez que sea necesario. Una variable queda  definida por su NOMBRE Y SU VALOR. El contenido  de la variable  puede cambiar a lo largo del programa. Las variables en processing deben ser DECLARADAS antes de ser usadas para definir el tipo  de dato que aceptará. 
Es importante que se asigne el valor correcto  al  tipo  de variable que hayamos declarado previamente para evitar errores. El nombre de la variable debe empezar siempre en minúscula y luego pude seguirle practicamente cualquier cosa. 

int x; //declaramos la variable x del tipo entero
flota y; // declaramos la variable y del tipo  flotante (decimales)
boolean a; //declaramos la variable a del tipo  booleana
x=10; //  asignamos el valor 10 a la variable x
int x=10; //declaramos la variable x del tipo entero y le asignamos el valor 10
float x,y,z; //declaramos tres varibles del tipo  flotante.
int z=10,5 // error de asignación de variable. 


3.- LAS EXPRESIONES: 
LOS OPERADORES Y LOS COMPARADORES.
Las expresiones son como frases que van acompañadas de algún OPERADOR  o COMPARADORES y pueden ser tan básicas como un sólo número, o una cadena comleja de elementos. Una expresión siempre tiene un valor determinado.

OPERADORES ARTIMÉTICOS: +.-,*,/, %(módulo), ( ), ++(incremento), --(decremento), +=(asignación con suma), -=(asignación  con resta), - (negativo).
OPERADORES LÓGICOS: &&(AND), ||(OR), !(NOT).
COMPARADORES: >,<,==, (igualda a),!=(distinto de),<=,>=


EXPRESIÓN     VALOR: 
5                               5
10.5*2                    21
((3+2)*(-10))+1      -49    //los paréntesis  establecen  la prioridad en el operador.
6>3                          true
5<10                       false
9%3                           0
9%2                           1
x++;                         //equivale a x=x+1. Operador de incremento.
x--;                          //equivale a x=x-1. Operador de decremento.
x+=5;                      //equivale a x=x+5. Operadro  de suma asignada.
x*=5;                      //equivale a x=x*5. Operadorde multiplicación asignada.
x=-x                       //x=x*(-1). Cambiamos el signo positivo/negativo.

Una expresión o conjunto de ellas es una  instrucción que forma una acción.El PUNTO Y COMA representa el "terminador"  de dicha acción.

Las acciones pueden: DECLARAR UNA VARIABLE, ASIGNAR UN VALOR A UNA VARIABLE, EJECUTAR UNA FUNCIÓN, CONSTRUIR UN OBJETO,  etc. Si  no se usa correctamente el punto y coma, el  programa daría un error. 

//ejemplo  de variables con operadores aritméticos
int a=30;
int b=40;
line(a,0,a,height);
line(b,0,b,hiight);
strokeWeight(4);
line(b-a,0,b-a,height);



4.- LA ESTRUCTURA SECUENCIAL. 
Inicialmente si no ese especifíca lo contrario los códigos de un programa se van ejecutando de forma secuencial. Se asignan valores a las variales, se leen datos de partida, se procesan y se obtienen la salida de otros datos.

Veamos algunos  ejemplos de este tipo de estructura.

1.-  Calcula  el área de un triángulo.
//area de un triángulo
float b=30;
float h=40;
float area;
area =b*h*0.5;
print("El area del triángulo es: "+area+"cm2");

2.- Calcular IVA de un productos que cuesta  40,30euros.
//area de un triángulo
float producto=40.30;
float IVA=21;
float valor;
valor =producto+(producto*IVA/100);
print("El coste toal  es: "+valor+"euros");

3.- Calcular la hipotenusa de un triángulo rectángulo a=3, b=4.


5.-LAS FUNCIONES:    
Las funciones nos sirven para organizar el código y poderlo reciclar luego. Una función es una estructura que en un momento dado en el flujo del programa es invocada. Cuando esto pasa, las instrucciones que estén contenida en la función se van a ejecutar.

Una función permiten ejecutar varias acciones asociadas a unos posibles parámetros que se introducen entre paréntesis. En processing  las funciones  se escriben en minúsculas y terminan con un  PUNTO Y COMA final de instrucción. En processing existe una  sensibilización entre mayúsculas y minúsculas, en el caso  de  las funciones, estas deben  escribirse  en  minúsculas. Sin embargo, los  espacios en blanco no  le afecta como si lo hacen  en otros lenguajes.

En processing muchas de estas funciones son gráficas, el orden en que dibujemos las  figuras en el código, definirá  que figuras aparecen unas sobre  otras en la ventana de representación. Si dibujamos un rectángulo en primera posición y un círculo en la siguiente, el rectángulo aparecerá por detrás del círculo.

size(x,y); 
En processing la función más básica que se utiliza es la que inicialmente nos sirve para establecer la ventana (CANVANS) de trabajo en píxeles. Por defecto esta ventana es de 100x100 píxeles pero podemos hacerla tan grande como nuestra memoria RAM de la máquina donde trabajamos pueda aguantar.

Cada píxel, tiene su lugar en la ventana (CANVANS) que diseñemos. Esta posición se expresa mediante coordenadas (x,y)  (ancho por alto en píxeles), con el punto (0,0) en la esquina superior izquierda de la ventana. Cada parámetro dentro del paréntesis  debe separarse por UNA COMA.

Los  parámetros introducidos entre  paréntesis se separan por un coma y el fin de la instrucción se establece con un PUNTO Y COMA.

point  (x,y);
Recuerda que nuestra ventana representa un eje de coordenadas cartesianos  donde el punto (0,0) se situa en la parte superior izquierda y que el desplazamiento horizontal hacia  la derecha representa el  +X y el eje vertical hacia abajo representa el  +Y. Se pueden  utilizar valores de coordenadas  negativos  pero la imagen  que vaya fuera  de la ventana no  se visualizará.
point(10,10);
point(20,20);

line(x1,y1,x2,y2);
Una línea definida por la unión entre los dos puntos (x1,y1) y (x2,y2).

triangle(x1,y1,x2,y2,x3,y3); 
Un triángulo definido por la unión de sus tres vértices.

quad(x1,y1,x2,y2,x3,y3,x4,y4); 
Un cuadrilátero (polígono de cuatro lados) definido en función  de  sus ocho parámetros para poder  dibujar: cuadrados, rectángulos, paralelogramos y  cuadriláteros irregulares.

rect(x,y,ancho,alto); 
Para dibujar rectángulos funciona de  manera diferente, en esta ocasión se marca el punto de coordenadas x,y para luego definir el ancho y el  alto. Si marcamos el mismo valor en el ancho  y alto  dibujaremos un cuadrado. Si añadimos un quinto  parámetro añadiremos lo que es el "radio" de redondeo  del contorno que también se podría hacer esquina  por esquina añadiendo cuatro parámetros más de "radios de contorno".

ellipse(x,y,ancho,alto); 
Del  mismo modo  ahora podemos dibujar elipses. Si el ancho y el alto son iguales dibujaremos círculos.

text(datos,x,y);
Imprime en la pantalla el valor asignadoa datos que puede ser char, string, int o float y lo representa a partir de la coordenada x,y. Si queremos que salga el  texto deberemos entrecomillarlo; "Texto"



EL RETORNO EN LAS FUNCIONES
Otra cosa que pueden hacer las funciones, y aquí, aunque puede parecer que la cosa se complica, es cuando las cosas se vuelven interesantes. Además de poder o no recibir parámetros, una funcion puede o no devolver (retornar) valores. Hasta ahora hemos visto funciones que nunca devuelven nada. Este tipo de funciones simplemente se invocan, con o si parámetros, si más.

¿Pero qué pasa si una función devuelve un valor? ¿A quién se lo devuelve y cómo lo gestionamos? Pues de hecho es bien sencillo. Cuando invocamos una función que devuelve un valor, hemos de asignar éste valor a una variable (o utilizarlo directamente). Es algo que de hecho hemos estado ya haciendo con random.

Por ejemplo, si tenemos una función llamada calculines que nos realiza los dificilísimos calculos de hacer la media entre dos valores, la asignaríamos a una variable llamada resultado:

int resultado;
resultado = calculines(32,439);


Y la función en sí sería algo así:
int calculines(int a_, int b_) {
  int aRetornar;
  aRetornar = (a_+b_)/2;
  return aRetornar;
}



Otro aspecto muy importante ahora es la declaración de la función. Y aquí por fin cobrará sentido el famoso void: Cuando declaramos una función que devuelve un valor, debemos especificar el tipo de datos que devuelve al declararla. Así, una función que devuelve un entero se declararía por ejemplo así:
int dameUnEnteroBonito(){
  //instrucciones
}

Y una que nos ha de devolver un float:
float dameUnFlotador(){
   //instrucciones
}


Y, finalmente, hay que tener SIEMPRE, en una función que retorna algo, una instrucción de retorno al final. Dicha instrucción se llama return y va seguida de un valor que se retorna, valga la redundancia...
float dameUnFlotador(){
   //instrucciones donde flotador es una variable del tipo float
   return flotador;
}



Ejercicio:
1.- Media aritmética entre dos números utilizando una función y una previa configuración con setup():

void setup() {  //en  llamadas de funciones  se debe utilizar setup()
size(100,100);
float m=media(12,6);
println(m);
}
float media(float n1,float n2) {
  float av=(n1+n2)/2;
  return av;
}

2.- Convierte el valor de la temperatura de ºFahrenheit a ºCelsius. 
void setup() {
float c=fac(451);
println(c);
}
float fac(float t) {      //diseñamos al función de conversión de grados
  float f=(t-32)*(5.0/9.0);   //es necesario poner 5.0 para que la división sea float 
  return f;
}





6.- EL COLOR
Los ejemplos vistos antes han  utilizado un  fondo por defecto de color gris claro, líneas  negras y figuras blancas. Para cambiar estos  valores  es necesario  intercalar instrucciones  adicionales.
Trabajar con colores en un ordenador es  diferente a hacerlo sobre un lienzo. Por ejemplo, unir  todos los colores en un PC tiene como  resultado el color blanco, mientras que  en un lienzo de pinturas reales tiene como resultado el color  negro. En un PC los colores se mezclan con luz, la pantalla es una superficie  negra donde se añaden luces coloreadas, esto se conoce como colores aditivoss, en  contraste del método de color sustractivo para el papel o lienzo.
La forma más común  de especificar un color en un PC es mediante  la terna  de valores  RGB que  ajusta la cantidad  de luz roja, verde y azul en cada píxel  de la pantalla  por el método aditivo.
Para  colorear nuestras figuras debemos establecer estas instrucciones  antes de las figuras que queramos dibujar. Estas paletas de colores se mantendrán hasta nueva instrucción que  las haga cambiar.

background(x); 
Con esta función se establece el color de fondo de la ventana previamente diseñada. El 0 representa el negro y el 255 el blanco con un rango de tonos de grises entre medias.
background(0);    //fondo negro
background(255,0,0);   //fondo  rojo  puro.

background(r,g,b,alfa); 
Cada vez que utilicemos una instrucción que indique un color podremos usar uno,tres o cuatro números entre 0 y 255 para indicar el tipo de color.
Cuando trabajamos con Processing, el color lo designamos con el RGB en un peso de 8 BITS:

RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA

Esto significa que cada unos de los cuatro valores (rojo, verde, azul y alfa) ocupa 8 bits (un byte) en memoria. Es decir, 256 valores posibles. Así pues, el color en Processing tendrá un rango de 0 a 255 por cada uno de estos cuatro valores. Si no se especifica el parámetro alfa, se entiende que su valor es máximo, 255, y que por lo tanto no hay transparencia (la opacidad es total).


fill(r,g,b,alfa); 
Para dar color de relleno a las  figuras que a continuación se vayan a dibujar. Si no se define un valor de relleno se usa por defecto el valor 255, blanco.
fill(255,255,0,32); //relleno amarillo con muy poco ALFA

nofill( );  // con esta instrucción establecemos que no  queremos relleno alguno. Esta función no tiene parámetros simplemente se pone tal cual.

stroke(r,g,b,alfa); 
Para  dar color al marco  de la figura que vayamos  a dibujar. Si no se define un valor de contorno, se usa el valor  por defecto 0, negro.

strokeWeight(x); // se utiliza para establecer el ancho del trazo

nostroke(); //Especifica que a partir de este punto no se dibujen los trazos. No recibe parámetros. Es decir, no hay que poner nada entre los paréntesis. Ningún valor. Simplemente se invoca la función.

smooth(); 
Esta instrucción  indica  que queremos suavizar  la figura a dibujar.

color(r,g,b,alfa);  
Con  esta función podemos almacenar en una variable tipo "color"  los  valores que vayamos  a trabajar. Después  de que una variable color se haya definido, se puede usar como  parámetro para  las funciones de background(), fill() y strocke().
color rosa=color(237,159,176);  //definimos  la variable  roja y la asignamos  un valor
background (rosa);  //hacemos uso de la variable color que hemos llamado  como rosa.



ACTIVIDADES DE FIGURAS BÁSICAS:
1º) Analizar el siguient código  y predecir su lógica. Comprobar el resultado editándolo luego en processing.

Ejemplo 1.1.:
size(300,300);
background(255);
fill(127,255,0);
stroke(255,0,0);
rect(50,50,200,200);


Ejemplo 1.2:
size(200,200);
background(0);
fill(0,0,255);
stroke(255,0,0);
ellipse(100,100,110,50);
fill(0,255,0);
rect(100,100,40,35);


Ejemplo 1.3:
size(600,400);
background(0);
fill(255,0,0);
strokeWeight(5);
stroke(255);
ellipse(250,150,200,80);
noStroke();
fill(0,255,0,127);
rect(250,150,200,120);
stroke(200,200,20);
line(100,100,350,210);



2º.- Dibuja una pantalla de bienvenida parecida a esta:


size(400,400);
background(125);
fill(255);
PFont fontA = loadFont("ArialMT-48.vlw"); //primero ir a herramientas/cargarfuente
textFont(fontA, 14);
String s = "Have a nice day!";
strokeWeight(5);
fill(255,255,0);
ellipse(width/2,height/2,80,80);
fill(0);
ellipse(width/2-17,height/2-17,5,5);
ellipse(width/2+17,height/2-17,5,5);
noFill();
arc(width/2,height/2,50,50, 0, PI);
textSize(40);
text(s,width/2 - textWidth(s)/2,35);


3º.- Dibuja una figura libre como estas.




7.-FORMATO  DE COLOR  RGB vs HSB
colorMode(RGB, 255,255,255); // para rojo, verde y azul
Processing usa por defecto el formato de color  RGB y por tanto,  valores de  0 a 255. 

colorMode(HSB,360,100,100);
Pero también se puede trabajar  en el modo  de color HSB donde los tres últimos parámetros  especifican el MATIZ o tipo de color (amarillo, rojo,  naranja,  verde, violeta...), su SATURACIÓN o grado de pureza de un color, y el BRILLO, es decir, su relación luz-oscuridad. Estos tres parámetros van del 0.0 al 1.0. o en mejor opción según la nomenclatura que habitualmente se usan  en otros programas.En este caso  usaremos de 0 a 360 los  grados  alrededor de la rueda de color, y de 0 a 100 como valores porcentuales para el segundo  parámetro  de saturación y para el tercer parámetro de brillo.

//ejemplo modo  HSB. 
//Comprueba como una alta oscuridad nunca es recomendable según que circunstancias.
size(200,200);
strokeWeight(5);
colorMode(HSB);
stroke(132,255,255); //azul,máxima saturación y máximo brillo
line(10,10,200,200);
stroke(132,0,255); //azul, mínima saturación (blanco) y máximo brillo
line(30,10,200,200);
stroke(132,255,0); //azul, máxima saturación, mínimo  brillo (oscuro).
line(50,10,200,200);
stroke(132,127,127); //azul,media saturación, medio brillo.
line(70,10,200,200);
stroke(132,200,200); //azul,alta saturación, alto brillo.
line(90,10,200,200);
stroke(132,50,200); //azul,baja saturación, alto brillo.
line(110,10,200,200);
stroke(132,200,50); //azul,alta saturación, bajo brillo.
line(130,10,200,200);
stroke(132,155,230); //azul, media saturación, alto brillo.
line(130,10,200,200);

Trabajar en el formato HSB (matiz,saturación,brillo) es un camino  más lógico puesto que con el sistema RGB obtenemos resultados más inesperados. Veamoslo con el siguiente ejemplo:

Con este código cambiamos el color de azul a verde en modo RGB y par ello es necesario calcular  loos tres valores de color y además la saturación cambia inesperadamente en el centro del proceso.
colorMode(RGB);
for (int i=0; i<100; i++) {
  float r=61+ (i*0.92);
  float g=156+ (i*0.48);
  float b=204- (i*1.43);
  stroke(r,g,b);
  line(i,0,i,100);
}
Mientras, con este otro modo  HSB sólo es necesario alterar un número y además el matiz cambia suavemente e independientemente de las otras propiedades del color.

colorMode(HSB,360,100,100);
for (int i=0; i<100; i++) {
  float newHue=240- (i*1.2);
  stroke(newHue,70,80);
  line(i,0,i,100);
}


8.- LAS ESTRUCTURAS CONDICIONALES.
Con esta estructura un programa puede ejecutar una línea de código u otra dependiendo de si se cumple una determinada condicion (true). Por ejemplo el programa dibuja una línea o una elipse dependiendo del valor de una variable.

if (condición) {   //cuidado con no poner punto y coma en esta línea
acciones;
}
else {           
acciones;
}

Por ejemplo, analizando el siguiente código vemos un resultado u otro en el uso de las variables booleanas. Si cambiamos los valores true/false de los booleanos podemos entender como funcionan el "y" y el "o" lógicos:

boolean condiUno = true;
boolean condiDos = false;
//comprobamos el "OR" lógico
if(condiUno || condiDos){
print("se cumple el ||");
}

else {
print("no se cumple el ||");
}
//comprobamos el "AND" lógico
if(condiUno && condiDos){
print("se cumple el &&");
}

else {
print("no se cumple el &&");
}



ACTIVIDADES CON CONDICIONALES.
1.- Dibuja un círculo o un cuadrado según el valor de una variable.
size(200,200);
int x=10;
if (x>100) {
 ellipse(50,50,50,50);
}
if (x<100) {
 rect(30,30,40,40);
}
line(20,20,80,80);

2.- Analiza el siguiente código donde se usan operadores lógicos y describe que ocurrirá.
size(200,200);
int a=10;
int b=20;
if ((a>5)||(b<30)) {
  line(20,50,80,50);
}
if ((a>15)||(b<30)){
  ellipse(50,50,30,30);
}

3.- Dado un número, indicar si es par o impar.
int a=10;
int valor=a%2;
if (valor==0) {
  print("es par");
}
else{
  print("es impar");
}

4.- Calcular la raiz de una ecuación de segundo grado.
int a=16;
int valor;
if (a>0) {
  print("la raiz de "+a+ "es : "+sqrt(a));
}
else{
  print("El número "+a+" no tiene raiz real");
}

5.- Indicar si dos números son divisibles entre ellos.
6.- Dados dos números que los imprima en forma ascendente.
7.- Calcular el número de pulsaciones que una persona debe tener según su edad y sexo.
8.- Dados dos números, si son iguales que los multiplique, si el primero es mayor que lo reste al primero y si no que los sume.
9. Dados tres números, que imprima el mayor de ellos.



9.- LAS ESTRUCTURA DE REPETICIÓN CON FOR.
Una de las bondades de los ordenadores es la de hacer cálculos a gran velocidad. Con estructuras de bucle o de repetición se consigue a través de pocos líneas de código que se puedan repetir una y otra vez hasta que nosotros queramos bajo la siguiente sintáxis:

FOR (indicador, condición, actualización) { acciones }

Mientras que la condición sea true, el ciclo continuará con la actualización que le  indiquemos.

for (int i=1;1<10;i++) {  //cuidado no poner aquí el punto y coma
 acciones;
}


Ejemplo:
for(int i=0; i<1000; i=i+1){
  println(i);
}

//con este código nos ahorramos muchas líneas por escribir

Pero vamos a lo gráfico. Imaginad que queremos crear un centenar de elipses en posición y de tamaño aleatorio. Sin un bucle, habría que hacer una misma operación cien veces. Pero con un for  es tan fácil como hacer lo siguiente:

size(200,200);
background(255,0,0);
for(int i=0; i<100; i++){
  float posX = random(width);
  float posY = random(height);
  float tamano = random (60);
  ellipse(posX,posY,tamano,tamano);
}



Un ejemplo donde el bucle nos sirve para realizar una acción un cierto número de veces, pero también podemos hacer que el mismo valor de "i" que incrementa el valor del bucle sea utilizado como un elemento gráfico más:

  size(300,300);
  frameRate(30);
  smooth();
  fill(255,32);
  noStroke();
  background(255,0,0);
  for(int i=0; i<width; i+=4){
     float tamano = random (i);
    ellipse(i,i,tamano,tamano);
  }


ACTIVIDADES CON FOR:
1.- Analiza el siguiente código e indica qué tipo de dibujo aparecerá.
for (int i=10;i<80;i+=5) {
  line(20,i,80,i+15);
}


2.-Analiza el siguiente código e indica qué tipo de dibujo aparecerá.
noFill();
for (int i=150;i>0;i-=10) {
  ellipse(50,50,i,i);
}


3.- Analiza el siguiente código y modificalos para hacerlo diferente.

size(200,200);
color rosa=color(237,159,176);
background(rosa);
colorMode(HSB);
for (int i=0;i<200;i+=10) {
  strokeWeight(3);
  stroke(i,255,255);
  line(i,0,i,200);
}

4.- Dibuja varios círculos de izquierda a derecha hasta llegar al final de la ventana.
int pos;
size(300,100);
pos = 10;
for (int i=1;i<100;i++) {
if(pos <= 250){
pos = pos + 10;
}
ellipse(pos,50,20,50);
}

5.- Calcular la suma de los  N=10 primeros números naturales.
6.- Calcular el factorial  de un  número.
7.- Imprimir la tabla de multiplicar de un número cualquiera. (multiplicando, multiplicador y producto)



CURVAS SIMPLES CON FOR.
Dado un valor de x normalizado entre 0.0 y 1.0 podemos representar las curvas simples bajo la expresión y=x^n utilizando el ciclo  For. Recuerda que en processing nuestra pantalla es como un eje de coordenadas cartesianos donde el 0,0 está situado en la esquina superior izquierda y los ejes positivos de desplazan hacia la derecha para el X y hacia abajo para el  Y.

Por ejemplo:
1.- Dibujemos y=x^2
size(200,200);
int n=2;
for (int x=0;x<200;x++) {
  float y=pow(x,n);
  point(x,y);
}


...pero para  verlos mejor debemos ajustar la escala de representación utilizando la instrucción norm(valor,menor,mayor);  de esta forma hacemos que el resultado se ajuste a un rango.

size(100,100);
float n=5;
for (int x=0;x<100;x++) {
  float a=norm(x,0.0,100.0);     //escalamos a 1/10 
  println(a);
  float y=pow(a,n);
  y*=100;
  point(x,y);
}


ACTIVIDAD: sustituye el  point() por una figura básica y así  poder ver la onda más fácilmente. 



Nuevas curvas con:  translate( );
En processing la posición de origen por defecto se encuentra en el (0,0), esquina superior izquierda, y hace referencia a una posición de los píxeles. Con la función traslate() podemos cambiar este sistema de coordenadas.

1.- Dibuja y=x^3

//Dibujemos la curva y=x^3
size(300,300);
translate (width/2,height/2);
background(255, 204, 0);
stroke(200);
line(-width/2,0,width/2,0);
line(0,-height/2,0,height/2);
stroke(0);
for (int x=-200; x<200; x++) {
  float n=norm(x,0.0,100);
  float y=pow(n,3);
  y*=100;
  point(x,y);
}

2.- Dibuja una onda senoidad:  y=sen(angulo)
size(500,300);
translate (0,height/2);
background(255, 204, 0);
stroke(200);
line(0,0,width,0);
stroke(0);
int A=80; //amplitud de la onda
float F=0.01; //frecuencia de la onda
float angulo=2*PI*F;
for (float x=0; x<=width; x+=0.5) {
  float y=A*sin(angulo*x);
  point(x,y);
}


3.- Dibuja una espiral.

size(500,500);
translate (width/2,height/2);
background(255, 204, 0);
stroke(200);
line(-width/2,0,width/2,0);
line(0,height/2,0,-height/2);
stroke(0);
smooth();
float radio=1;
float px=0; //empezamos desde el centro
float py=0; 
for (int deg=0; deg<360*10;deg+=10) {
  float angulo=radians(deg);
  float x=(cos(angulo)*radio);
  float y=(sin(angulo)*radio);
  line(px,py,x,y);
  radio=radio*1.03;
  px=x;
  py=y;
}






ITERACCIÓN ANIDADA CON FOR. 

Con una estructura de FOR producimos repeticiones de UNA dimensión. Anidando podemos obtener con processing efectos de DOS dimensiones.

for (int x=10; x<100; x+=10) {
  for (int y=10;y<100;y+=10) {
     point (x,y);
  }
}

ACTIVIDAD:
1.- Diseña  un  patterns (fondos y texturas) usando repeticiones con anidación.
Ejemplo:
noStroke();
smooth();
for (int y=-10; y<=100; y+=10) {
  for (int x=-10;x<=100;x+=10) {
     fill (x*1.4,y*1.4,(x+y)*1.4);
     ellipse (x+y/8.0,y+x/8.0, 15+x/2,10);
  }
}


10.- LAS ESTRUCTURA DE REPETICIÓN  CON WHILE

//Veamos un ejemplo

size(255,255);
int i=0;
while(i<height) {
    stroke(i,0,0);
    line(0, i, width, i);
    i = i + 2;
 }


Hay que ir con cuidado con este tipo de bucle: es muy fácil crear un bucle infinito, que en el caso de Processing hará que se cuelgue la aplicación. Esto pasaría si en el ejemplo anterior olvidamos la línea i=i+2; que es la que permite que en algún moemento deje de cumplirse la condición while(i<height) y por consiguiente se rompa el bucle (y se continúe ejecutando el código).

Si acabáis provocando un loop infinito, en un PC deberéis abrir el Administrador de Tareas (ctrl+alt+supr, o bién right-click en la barra de tareas --> administrador de tareas), y en la pestaña aplicaciones seleccionar Processing y escoger "finalizar tarea". Si esto no funciona (u os cansáis de esperar), el la pestaña procesos podéis matar el proceso java. Al hacer esto último pararéis Processing y perderéis qualquier cambio en el código después del último "save".




12.- LAS FUNCIONES BÁSICAS DE  PROCESSING: "SETUP" y "DRAW". Processing en movimiento.

setup() y draw() son las dos funciones principales de Processing. Las que se ejecutan siempre. Primero setup(), una sola vez, y luego draw() repetidamente. Esto es lo que rompe la lineariedad estricta en la lectura y ejecución del código, y lo que nos permite hacer cosas mucho más interesantes que simples dibujos.

Hasta ahora las hemos ignorado porque el código que utilizábamos se ejecutaba una sola vez, de arriba a abajo. Ahora, todo lo que esté dentro de draw() se va a ejecutar repetidamente, también de arriba a abajo, hasta que paremos el programa (también hay la opción de pararlo con código, pero por ahora lo ignoramos).

int y=0;   //tipo y nombre variable, operador y asignación
void setup() {     //el  área entre {y} es un bloque
   size(300,300);  //función con parámetros
}
void draw() {
     line(0,y,300,y);   //función gráfica con parámetros
     y+=4;    //expresión y=y+4
}




Mirad el código, analizadlo, y después lo ejecutáis a ver si se cumplen vuestras predicciones:
void setup() {
  size(500, 400);
  background(10, 80, 100);
}
void draw() {
  stroke(255, 255, 255);
  fill(160, 220, 90);
  ellipse(mouseX, 200, 300, 300);
  fill(160, 210, 230);
  rect(245, mouseY, 10, 240);
  fill(255, 255, 255);
  ellipse(mouseX, mouseY, 70, 70);
}


//En este caso la instrucción mouseX actua como variable para dar al programa cierta INTERACTIVIDAD.

ACTIVIDADES:
1.- Espiral en movimiento


float x=0;
void setup() {
size(500,500);
background(255, 204, 0);
stroke(200);
line(-width/2,0,width/2,0);
line(0,height/2,0,-height/2);
stroke(0);
smooth();
}

void draw() {
float radio=1;
float px=0; //empezamos desde el centro
float py=0;
translate (width/2,height/2);
rotate(x);
x+=3;
frameRate(10);  //velocidad de draw() -por defecto 30 fps-
background(255, 204, 0);
for (int deg=0; deg<360*10;deg+=10) {
  float angulo=radians(deg);
  float x=(cos(angulo)*radio);
  float y=(sin(angulo)*radio);
  line(px,py,x,y);
  radio=radio*1.03;
  px=x;
  py=y;
}
}


2.- Ahora te toca a tí hacer un programa dinámico y artístico. Puedes ver algunos ejemplos en la siguiente galería: http://hello.processing.org/gallery/




La programación en  processing con draw( ).
Analiza los siguientes códigos:
int numero;
void setup(){
numero = 13;
}
void draw(){
numero = numero + 1;
println(numero);
}


// y otro ejemplo sería el siguiente
float pos;
void setup(){
size(400,100);
pos = 13;
}
void draw(){
pos = pos + 0.1;
ellipse(pos,50,20,20);
}


//..y si usamos algunas de las variables del sistema, con la ellipse, podemos ver como
combinando éstas con una variable convencional y con setup() y draw() podemos por fin tener una
cierta (aunque básica) interactividad:
int sz = 30;
void setup(){
size(200,200);
}
void draw(){
ellipse(mouseX,mouseY,sz,sz);
}


//Y finalmente, añadiendo una sola línea, borramos en cada frame el dibujo anterior para dar la sensación de movimiento:
int sz = 30;
void setup(){
size(200,200);
}
void draw(){
background(0);
ellipse(mouseX,mouseY,sz,sz);
}




int x;
void setup() {
  size(800, 600);
    stroke(255,0,0);
}
void draw() {
  ellipse(x, height/2, 60, 60);
  x = x + 5;
}
void keyReleased() {
  x = 0;
}




ACTIVIDADES:
1.- Dibuja una elipse que se desplaze horizontalmente y que a la vez vaya cambiando de color de fondo de forma gradual.

int x;
void setup(){
  size(255,255);
}

void draw(){
  background(x,0,0,20);
  fill(0,mouseX,mouseY);
  ellipse(x,122,30,30);
  x=x+1;
  if(x>255) x=0;
}

2.- Dibuja una onda senoidal y cosenoidal. 

int x;
void setup() {
  size(800, 600);
    strokeWeight(2);
}

void draw() {
  stroke(255,0,0);
  point(x, height/2+sin(radians(x))*100);
    stroke(0,255,0);
  point(x, height/2+cos(radians(x))*100);
    x = x + 1;
}

3.- Dibuja una pelota que rebota y simula un espacio cerrado. 

int posX, posY, velX, velY;
int sz = 20;
void setup(){
  size(200,150);
  posX = width/2;
  posY = height/2;
  velX = 5;
  velY = 5;
}
void draw(){
  background(0);
    //actualitzem posicions
  posX = posX+velX;
  posY = posY+velY;
    //dibuixem
  ellipse(posX,posY,sz,sz);
  //comprovem la posició X
  if((posX<0)||(posX>width)){
    velX = -velX;
  } 
    //comprovem la posició Y
  if((posY<0)||(posY>height)){
    velY = -velY;
  } 
}


Compara ahora con este otro  código  y trata de decir lo que ocurre de diferente antes de probarlo en processing:
int pos, vel;
int sz = 20;
void setup(){
size(300,200);
pos = width/2;
vel = 5;  //con carácter vectorial y signo positivo/negativo
}
void draw(){
background(0);
pos = pos+vel;
  //actualitzamos la posición
ellipse(pos,height/2,sz,sz);
//comprobamos si está en los límites de la ventana
//si lo está, invertimos el signo de la velocidad:
if((pos<0)||(pos>width)){
vel = -vel;
}

}

4.- Y finalmente, utiliza los condicionales para hacer crecer y decrecer la pelota, ya sea para que parezca que respire, o para simular un eje Z.

5.- Dibuja una elipse a cada clic de ratón.
void setup(){
  size(255,255);
}
void draw(){
   fill(0,20);
  rect(0,0,width,height);
  noCursor();
  noStroke();
  fill(255);
  ellipse(mouseX,mouseY,30,30);
 }


6.-  Dibuja elipses con el ratón donde se pueda cambiar de color según las teclas pulsadas: r,b,up/down. 
Modifica el código anterior para que según se pulse el botón derecho dibuje cuadrados y cuando pulse botón izquierdo del ratón dibuje elipses, manteniendo los colores según las teclas.
void setup() {
  size(255, 255);
}
void draw() {
  background(255);
  noCursor();
  ellipse(mouseX, mouseY, 30, 30);
}

void keyReleased() {
  if (key=='r') {
    fill(255, 0, 0);
  }
  if (key =='b') {
    fill(0, 0, 255);
  }
  if (keyCode == UP) {
    fill(0, 255, 0);
  }
  if (keyCode == DOWN) {
    fill(255);
  }
}


7.- Dibuja una elipse que vaya aumentando y disminuyendo de tamaño de forma cíclica.
int tamanoMinimo = 20;
int tamanoMaximo = 175;
int intervalo = 3;
boolean creciendo = true;
int tamanoPelota = 2;
void setup(){
  size(200,200);
  smooth();
  strokeWeight(3);
}
void draw(){
  background(255,255,127);
  //colores
  fill(255,127,255);
  stroke(127,255,255);
  //El tamañoo de la pelota debe cambiar según estemos creciendo
  //o decreciendo:
  if(creciendo==true){
    tamanoPelota = tamanoPelota + intervalo;
  }
  else { //es decir, si no está creciendo
    tamanoPelota = tamanoPelota - intervalo;
  }
  ///////////////////////
  //Y aqui­ hay que comprobar si se llega a un tamañoo limite,
  //para cambiar el ciclo crecer decrece
  if(tamanoPelota > tamanoMaximo){
    creciendo = false;
  }
  if(tamanoPelota < tamanoMinimo){
    creciendo = true;
  }
  //Finalmente, dibujamos la pelotita
  ellipse(width/2,height/2,tamanoPelota,tamanoPelota);
}



13.- ALEATORIEDAD
La aleatoriead tiene una fundamental importancia en nuestra historia, especialmente en el arte moderno donde se  ha buscado un  contraste elevado entre una estructura rígida y el completo caos.

random(alto);
random(bajo,alto);

La función random() permite devolver un valor  decimal -float-, además acepta valores negativos, completamente aleatorio e inesperado de un rango especificado por parámetros.
Si queremos obtener un valor entero -int- deberemos recurrir a la función  int() para convertirlo después.

float f=random(0,5);
int i=random(0,5);  //ERROR DE EXPRESIÓN.
int i=int(random(0,5);  //ASÍ SI  CONVERTIMOS EL NÚMERO EN ENTERO.

EJEMPLOS:

1.- Pelotas aleatorias
int r;
void setup(){
  size(800,600);
}
void draw(){
  background(0);
    int x= int (random(1,width));
  int y= int (random(1,height));
  r=pelota(x,y);
  println(r);
}
int pelota(int a, int b){
  int tam = int (random(1,100));
  ellipse(a,b,tam,tam);
  return tam;
}


2.- Líneas 
background(0);
smooth();
stroke(255,60);
for (int i=0;i<100;i++) {
  float r=random(10);
  strokeWeight(r);
  float offset=r*5.0;
  line(i-20,100,i+offset,0);
}

3.- Texturas
size(700,500);
float power=3; //intensidad de la turbulencia
float d=8;  //densidad de la turbulencia
noStroke();
for (int y=0; y<height; y++) {
  for  (int x=0; x<width; x++) {
    float total=0.0;
    for  (float i=d; i>=1; i=i/2.0) {
      total +=noise(x/d,y/d)*d;
    }
    float turbulence=128.0*total/d;
    float base=(x*0.2)+(y*0.12);
    float offset=base+(power*turbulence/256.0);
    float gray=abs(sin(offset))*256.0;
    stroke(gray);
    point(x,y);
   }
}



4.- Desplazamiento  aleatorio de una pelota.
int pos, vel;
int sz = 20;
float viento;
void setup(){
  size(300,150);
  pos = width/2;
  vel = 2;
  //vamos a crear un viento:
  viento = random(-1,1);
}
void draw(){
  background(0);
  //actualitzamos la posición según sople el viento:
  if(viento > 0){
    pos = pos+vel;
  } 
  else { // si el viento es menor o igual a 0:
    pos = pos-vel;
  }
  //dibujamos
  ellipse(pos,height/2,sz,sz);
//para que se vaya repitiendo la misma acción:
  if(pos < 0 || pos > width){
    //reiniciamos posicion:
    pos = width/2;
    //creamos un viento:
    viento = random(-1,1);
    //println(viento);
  }
}

//En esta ocasión la pelota rebota, coge distintas velocidades y en cada clic de ratón se reinicia posición.

float posX, posY, velX, velY;
int sz = 20;
void setup(){
  size(300,200);
  posX = width/2;
  posY = height/2;
  velX = random(1,10);
  velY = random(1,10);
}
void draw(){
  background(0);
  //actualiza posicion
  posX = posX+velX;
  posY = posY+velY;
  //dibuixem
  ellipse(posX,posY,sz,sz);
  //comprueba posición x

  if((posX<0)||(posX>width)){
    velX = -velX;
  }
  //comprueba posiciónY
  if((posY<0)||(posY>height)){
    velY = -velY;
  }
}
void mousePressed(){
    posX = mouseX;
  posY = mouseY;
  velX = random(1,10);
  velY = random(1,10);
}


5.-Onda aleatoria de color rojo. 
 float a;
float inc;
void setup(){
  size(1260,120);
}
void draw(){
  //noLoop();
  noStroke();
  background(255,255,255);
  fill(255,0,0);
  for(int i=0; i<width; i=i+6){
    inc = inc + 0.1;
    a = noise(inc) * 60;
    ellipse(i, 30 + int(a), 3, 3);
  }
}





14.- IMÁGENES DE FONDO
Analiza y averigua como funciona el siguiente código donde se ha puesto una imagen de fondo y un cursor específico:

PImage fondo;
PImage cursor;
void setup() {
  size(800, 600);
    fondo = loadImage("background.jpg");
  cursor = loadImage("cursor.png");
}
void draw() {
  background(fondo);
  image(cursor, mouseX, mouseY);
}

EJERCICIO: con copy se puede copiar una parte de la imagen y que la amplie.
PImage img;
void setup() {
  size(800, 600);
    img = loadImage("murree.jpg");
}

void draw() {
  copy(img, 20, 20, img.width-40, img.height-40,
        20, 20, img.width-40, img.height-40);
}


/*
// metodo 2 - copiarlo a una imagen
PImage img;
PImage img2;
void setup() {
  size(800, 600);
   img = loadImage("murree.jpg");
  img2 = createImage(760, 560, ARGB);
  img2.copy(img, 20, 20, img.width-40, img.height-40,  0, 0, img.width-40, img.height-40);
}

void draw() {
  background(img);
  tint(255,200,200);
  image(img2, 20, 20);
}

*/










ARRAYS Y BUCLES
Donde el poder de los arrays se aprovecha mejor, es en su combinación con los bucles. Es bastante lógico que si tenemnos una estructura que puede guardar varias variables indexadas, y otra que nos permite iterar una misma acción en distintos elementos, las utilizemos conjuntamente.
Si no, sólo hay que mirar el último ejemplo de la sección anterior, donde el hecho de estar utilizando un array no nos reduce para nada la cantidad de código que hay que escribir. Sería exactamente lo mismo si utilizáramos cuatro variables. En cambio, si combinamos el array con un loop, podemos hacer algo así:

int[] listaPosiciones = { 14, 94, 120, 80 };
size(200,200);
// y dibujamos las elipses via loop:
  for(int i=0; i<4; i++){
     ellipse(listaPosiciones[i], 100,25,25);
 }



El resultado es exactamente el mismo, pero aquí, gracias a utilizar listaPosiciones[i] dentro del loop, estamos aprovechando las iteraciones del bucle para afectar todos los elementos del array. Cuatro en este caso, pero que pueden ser muchísimos más.

int[] listaPosiciones = { 14, 25, 39, 64, 94, 109, 122, 150, 170, 178, 190 };
size(200,200);
// y dibujamos las elipses via loop:
  for(int i=0; i<11; i++){
     ellipse(listaPosiciones[i], 100,25,25);
  }


¿Pero qué pasa cuando tenemos ya muchos elementos? Contarlos puede llegar a ser un poco tedioso, y, sobretodo, ineficiente si cambiamos en algún momento la cantidad de valores que le damos al array en la declaración.

Así, podemos substituir en el ejemplo anterior la línea de declaración de for loop por:

for(int i=0; i<listaPosiciones.length; i++){

Así utilizamos una variable que Processing ya calcula para nosotros: array.length que, como su nombre indica, corresponde a la cantidad de elementos presentes en el array en cuestión.
Atención: array.length nos indica el número de elementos en el array, pero el índice de dichos elementos empieza por 0, así que de hecho array[array.length] no existe! De aquí que en la condición le decimos al loop que se ejecute cuando "i" es MENOR a listaEnteros.length.
Finalmente, aprovechando el random para ser más eficientes, podemos hacer lo que sigue:

float[] listaPosiciones = new float[13];
size(200,200);
// creamos aleatoriamente todas las posiciones:
  for(int i=0; i<13; i++){
     listaPosiciones[i] = random(0,200);
  }
// y dibujamos las elipses via loop:
  for(int i=0; i<13; i++){
     ellipse(listaPosiciones[i], 100,25,25);
  }



EJEMPLO. Un ejemplo de pelotitas!
 int sz = 20;
int numeroBolas = 30;
//creamos un array de posicionesX con "numeroBolas" elementos:
float[] posicionesX = new float[numeroBolas];
//y creamos un array de posicionesY:
float[] posicionesY = new float[numeroBolas];
//creamos un array de velocidadesX con "numeroBolas" elementos:
float[] velocidadesX = new float[numeroBolas];
//y creamos un array de velocidadesY:
float[] velocidadesY = new float[numeroBolas];
void setup(){
  size(300,200);
  //inicializamos las posiciones y velocidades:
  for(int i = 0; i<numeroBolas; i++){
    posicionesX[i] = width/2;
    posicionesY[i] = height/2;
    velocidadesX[i] = random(1,3);
    velocidadesY[i] = random(1,3);
  }
}
void draw(){
  background(0);
  //iniciamos un bucle para que realize la acci�n para todos los
  //elementos del array:
  for(int i = 0; i<numeroBolas; i++){
    //actualitzamos las posiciones
    posicionesX[i] += velocidadesX[i];
    posicionesY[i] += velocidadesY[i];
    //comprobamos los bordes X
    if((posicionesX[i]<0)||(posicionesX[i]>width)){
      velocidadesX[i] = -velocidadesX[i];
    }
    //comprobamos los bordes Y
    if((posicionesY[i]<0)||(posicionesY[i]>height)){
      velocidadesY[i] = -velocidadesY[i];
    }
  }
  //acabado el proceso, creamos otro bucle
  //donde dibujamos las elipses:
  for(int i = 0; i<numeroBolas; i++){
    ellipse(posicionesX[i],posicionesY[i],sz,sz);
  }
}


Iniciamos una serie de posiciones en el eje X e Y en el punto medio del applet, y unas velocidades X e Y entre 2 y 6. Los cuatro arrays con los que trabajamos aquí son de floats. Una vez hecho esto, sin cambiar casi nada el código del ejemplo con una sola pelota, podemos multiplicar los elementos que afectamos. Y dentro del DRAW iniciamos un bucle para que realize la acción para todos los elementos del array.


También podemos dibujar las pelotitas de colores e implementar un evento al presionar el ratón que haga de reset:

int sz = 9;
int numeroBolas = 200;
//creamos un array de posicionesX con "numeroBolas" elementos:
int[] posicionesX = new int[numeroBolas];
//y creamos un array de posicionesY:
int[] posicionesY = new int[numeroBolas];
//creamos un array de velocidadesX con "numeroBolas" elementos:
float[] velocidadesX = new float[numeroBolas];
//y creamos un array de velocidadesY:
float[] velocidadesY = new float[numeroBolas];
void setup(){
  size(300,200);
  frameRate(30);
  //inicializamos las posiciones y velocidades:
  for(int i = 0; i<numeroBolas; i++){
    posicionesX[i] = int(random(width));
    posicionesY[i] = int(random(height));
    velocidadesX[i] = random(2,10);
    velocidadesY[i] = random(2,10);
  }
  noStroke();
}
void draw(){
  //background(0);
  colorMode(RGB,255);
  fill(255,25);
  rect(0,0,width,height);
  //actualitzamos las posiciones
  for(int i = 0; i<numeroBolas; i++){
    posicionesX[i] += velocidadesX[i];
    posicionesY[i] += velocidadesY[i];
    //comprobamos las posiciones X
    if((posicionesX[i]<0)||(posicionesX[i]>width)){
      velocidadesX[i] = -velocidadesX[i];
    }
    //comprobamos las posiciones Y
    if((posicionesY[i]<0)||(posicionesY[i]>height)){
      velocidadesY[i] = -velocidadesY[i];
    }
  }
  //dibujamos las elipses:
  for(int i = 0; i<numeroBolas; i++){
    colorMode(HSB,numeroBolas);
    fill(i,i,i);
    ellipse(posicionesX[i],posicionesY[i],sz,sz);
  }
}
void mousePressed(){
  //reinicializamos las velocidades:
  for(int i = 0; i<numeroBolas; i++){
    velocidadesX[i] = random(2,10);
    velocidadesY[i] = random(2,10);
  }
}





EJEMPLO CON  FUNCIONES

Entre otras ventajas, la funciones nos permiten organizar mejor el código Así, podemos por ejemplo crear un dibujo que requiere mucho código con una sola línea en el draw, y todo el código del dibujo contenido en una sola función, de manera que el DRAW nos queda así

/*
 Dibujamos un bicho con variables, y "limpiamos" el
 DRAW creando una funcion
 */

void setup(){
  size(250,150);
  noCursor();
  background(255,127,127);
}
void draw(){
  background(255,127,127);
  drawTheBitxo();
}


/////////////////////////////////////////////////
////// y AHORA LAS FUNCIONES:
//////////////////////////////////////////////
void drawTheBitxo(){
  int tamanoCuerpoX=40;
  int tamanoCuerpoY=65;
  int largoPatas=tamanoCuerpoY;
  int separacionPatas = tamanoCuerpoY/5;
  int diametroPies=8;
  int diametroOjos=10;
  int diametroPupilas=5;
  int separacionOjos=18;
  rectMode(CENTER);
  //colores
  fill(127,127,255);
  stroke(127,255,127);
  //patas
  line(mouseX-largoPatas/2,mouseY-separacionPatas*2,mouseX+largoPatas/2,mouseY-separacionPatas*2);
  line(mouseX-largoPatas/2,mouseY-separacionPatas,mouseX+largoPatas/2,mouseY-separacionPatas);
  line(mouseX-largoPatas/2,mouseY,mouseX+largoPatas/2,mouseY);
  line(mouseX-largoPatas/2,mouseY+separacionPatas,mouseX+largoPatas/2,mouseY+separacionPatas);
  line(mouseX-largoPatas/2,mouseY+separacionPatas*2,mouseX+largoPatas/2,mouseY+separacionPatas*2);
  //cuerpo
  rect(mouseX,mouseY,tamanoCuerpoX,tamanoCuerpoY);
  //pies
  ellipse(mouseX-largoPatas/2,mouseY-separacionPatas*2,diametroPies,diametroPies);
  ellipse(mouseX+largoPatas/2,mouseY-separacionPatas*2,diametroPies,diametroPies);
  ellipse(mouseX-largoPatas/2,mouseY-separacionPatas,diametroPies,diametroPies);
  ellipse(mouseX+largoPatas/2,mouseY-separacionPatas,diametroPies,diametroPies);
  ellipse(mouseX-largoPatas/2,mouseY,diametroPies,diametroPies);
  ellipse(mouseX+largoPatas/2,mouseY,diametroPies,diametroPies);
  ellipse(mouseX-largoPatas/2,mouseY+separacionPatas,diametroPies,diametroPies);
  ellipse(mouseX+largoPatas/2,mouseY+separacionPatas,diametroPies,diametroPies);
  ellipse(mouseX-largoPatas/2,mouseY+separacionPatas*2,diametroPies,diametroPies);
  ellipse(mouseX+largoPatas/2,mouseY+separacionPatas*2,diametroPies,diametroPies);
  //ojos
  stroke(0);
  fill(255);
  ellipse(mouseX-separacionOjos/2,mouseY-tamanoCuerpoY/2,diametroOjos,diametroOjos);
  ellipse(mouseX+separacionOjos/2,mouseY-tamanoCuerpoY/2,diametroOjos,diametroOjos);
  fill(0);
  ellipse(mouseX-separacionOjos/2,mouseY-tamanoCuerpoY/2,diametroPupilas,diametroPupilas);
  ellipse(mouseX+separacionOjos/2,mouseY-tamanoCuerpoY/2,diametroPupilas,diametroPupilas);
}



Ahora dibujaremos un satélite
/*
  Una funcion nos sirve para agrupar una serie de lineas de codigo
 que se ejecutaran cada vez que dicha funcion sea invocada.
  Esto nos sirve para organizar el codigo y hacerlo reciclable...
 */
void setup(){
  size(200,200);
  smooth();
}
void draw(){
  background(0);
  //invocamos la función, que definimos más adelante:
  dibujaUnSputnik(mouseX,mouseY);
}
//He aqui una funcion que dibuja un SPUTNIK:
void dibujaUnSputnik(int x_, int y_){
  strokeWeight(3);
  stroke(255);
  fill(255,0,0);
  line(x_-30,y_-30,x_+30,y_+30);
  line(x_-30,y_+30,x_+30,y_-30);
  ellipse(x_,y_,35,35);
}


//y usando la misma función ...con el ratón lo dibujamos
void setup() {
  size(300, 150);
  smooth();
  background(0);
}
void draw() {
  //nada
}
void mousePressed() {
  //dibujamos un sputnik donde estemos
  dibujaUnSputnik(mouseX, mouseY);
}
//He aquí una función que dibuja un SPUTNIK:
void dibujaUnSputnik(int x_, int y_) {
  strokeWeight(3);
  stroke(255);
  fill(255, 0, 0);
  line(x_-30, y_-30, x_+30, y_+30);
  line(x_-30, y_+30, x_+30, y_-30);
  ellipse(x_, y_, 35, 35);
}

//y otra vez con la misma función en este caso se desplaza a lo largo del eje x.

float pos = 20;
float vel = 1;
void setup() {
  size(300, 150);
  smooth();
  background(0);
}
void draw() {
  background(0);
  dibujaUnSputnik(pos, height/2);
  pos += vel;
  if (pos > width) {
    pos = random(width-50);
  }
}
//He aqui una función que dibuja un SPUTNIK:
void dibujaUnSputnik(int x_, int y_) {
  strokeWeight(3);
  stroke(255);
  fill(255, 0, 0);
  line(x_-30, y_-30, x_+30, y_+30);
  line(x_-30, y_+30, x_+30, y_-30);
  ellipse(x_, y_, 35, 35);
}






IMAGENES
Así, antes de empezar a utilizar un archivo de imágen, hay que declarar un objeto PImage, y después cargar en él el archivo con loadImage:
//creamos objeto
PImage laFoto;
//y cargamos imágen
laFoto = loadImage("gato.jpg");


Esto equivale más o menos a declarar un tipo de datos y asignarle un valor. Queda pues, utilizarlo. Y ya que estámos con imágenes, de paso la podríamos mostrar, con image():
size(300,200);
background(0);
//Creamos un objeto PImage, de nombre xfoto
PImage xfoto;
  //cargamos una foto en concreto en afoto
  //(que tiene que estar en el sketch folder, y moejor dentro de la carpeta data)

xfoto = loadImage("gato.jpg");
//y dibujamos la foto
image(xfoto, 50, 35);

Como habréis visto, dibujamos la imágen como quien dibuja cualquier otra cosa, básicamente con coordenadas. Así, no es difícil suponer que si ponemos esto en el DRAW podemos darle movimiento a la imágen, por ejemplo ligando su posición a la del mouse, como con los dos ejemplos que siguien:
//Creamos un objeto PImage, de nombre foto
PImage foto; 
void setup(){
 size(300,200);
 background(0);
 //cargamos un archivo de imagen en foto
 foto = loadImage("ramon.jpg"); 
}
void draw(){
 //y la dibujamos donde el mouse
 image(foto, mouseX, mouseY, 100,90); 
}

get( )
Algo muy interesante que podemos hacer con imágenes es manipularlas en base a su color. Para esto, primero hay que entender cómo analizamos el color. La base será la función get(), que nos da el valor (en forma de color) de un pixel determinado.
Así, en el ejemplo que sigue podemos pasearnos por la foto de Ramon y ver sobre qué color tenemos el cursor en cada momento.
//Creamos un objeto PImage, de nombre afoto
PImage foto;
void setup(){
  size(425,225);
  background(0);
  //cargamos un archivo de imágen en afoto
  foto = loadImage("ramon.jpg");
  //la dibujamos una sola vez 
  image(foto, 0,0);
  //cambiamos el cursor
  cursor(CROSS);
}
void draw(){
  //Declaramos una variable del tipo de datos color (un objeto color, para ser estrictos)
  color theColor;
  //y le asignamos, vía la función GET, el color del píxel en el que se encuentra el MOUSE
  theColor = get(mouseX,mouseY);
  //cargamos este color en el FILL
  fill(theColor);
  //y dibujamos el rectangulo de la derecha, que nos muestra el color sobre el que está el mouse
  rect(305,5,115,height-10);
}


VIDEO
De las imágenes fijas al vídeo. Antes de pasar al vídeo, vamos a crear un ejemplo con imágen fija que tenga sentido para hacer el salto:
//Creamos un objeto PImage, de nombre foto
PImage foto; 
void setup(){
 size(300,225);
 background(0);
 //cargamos un archivo de imágen en afoto
 foto = loadImage("ramon.jpg"); 
 //la dibujamos una sola vez 
 //image(foto, 0,0); 
 //desactivamos el contorno
 noStroke();
 //limitamos el FR para no colapsar processing
 frameRate(30);
}
void draw(){
 //background(0);
 int salto = 4;
 //Declaramos una variable del tipo de datos color (un objeto color, para ser estrictos)
 color theColor;
 //realizamos un doble loop para recorrer los píxels:
 for(int i=0; i<width; i+=salto){
 for(int j=0; j<height; j+=salto){
 //y asignamos a theColor, con foto.get(), el color EN LA FOTO del punto donde estamos
 theColor = foto.get(i,j);
 //preparamos el fill()
 fill(theColor);
 //y dibujamos un rect en el punto en que estamos
 //del color sobre el que estamos en la foto
 //con un random para hacerlo saltar
 //(sin random seria: rect(i,j,salto,salto);
 rect(i+random(-salto,salto),j+random(-salto,salto),salto,salto);
 }
 }
 //println(frameRate);
}

EJEMPLOS DE VIDEOS Y SONIDOS: http://processing.joan.cat/cs/s11_imatge/index.html




CLASES
 //Clases
void setup()
{
size(100,100); // Tamaño de ventana de la aplicación
noFill(); }
void draw() // Se repite a cada frame
{
Circulo c = new Circulo();
c.dibuja();
}
// Clase círculo
class Circulo
{
// Atributos
int r = int(random(50));
int x = int(random(100));
int y = int(random(100));
color c = color(random(255), random(255), random(255));
// Métodos
void dibuja()
{
stroke(c);
ellipse(x, y, r, r);
}
}



EJEMPLO DE CLASES: seguidor con el ratón
 //creamos un objeto
follower f;
void setup(){
  size(300,200);
  //instanciamos el objeto en medio de la pantalla, con velocidades 40 y tamaño 20
  f = new follower(width/2,height/2,40,40,20);
  noStroke();
}
void draw(){
  //fondo con alfa
  fill(255,255,0,2);
  rect(0,0,width,height);
  //ejecutamos el objeto
  f.run();
}
///////////////////////////////////////
///////////////////////////////////////
//Classe follower
class follower{
  //variables
  float myX, myY, vx, vy;
  int sz;
  //constructor
  follower(float _x, float _y, float _vx, float _vy, int _sz){
    myX = _x;
    myY = _y;
    vx = _vx;
    vy = _vy;
    sz = _sz;
  }
  //funcion run (la que invocamos des del draw)
  void run(){
    update();
    drawing();
  }
  //actualizacion (de posiciones, aqui­)
  void update(){
    //calculamos la distancia entre mouse y bola
    float distanceX = mouseX-myX;
    float distanceY = mouseY-myY;
    // actualizamos posicion a lo tortuga de zenon
    myX += distanceX/vx;
    myY += distanceY/vy;
  }
  //dibujo
  void drawing(){
    fill(0,16);
    ellipse(myX,myY,sz,sz);
  }

}

EJEMPLO  CLASES: Caminadores en grupo

//...y CREAMOS UN OBJETO WALKER, al que llamamos wkr
Walker[] wkrs = new Walker[1000];
//inicializamos
void setup() {
  size(300, 200);
  //Inicializamos los Walkers: les enviamos los par..‚metros step y tama

  for (int i=0; i<wkrs.length;i++) {
    wkrs[i] = new Walker(2, 5);
  }
}
void draw() {
  background(0);
  //ejecutamos los walkers
  for (int i=0; i<wkrs.length;i++) {
    wkrs[i].run();
  }
}
///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
/// CLASE WALKER
class Walker {
  //declaramos variables:
  int mySz, myStep;
  float myX, myY;
  //Constructor: se ejecuta al crear la instancia del objeto
  Walker (int _st, int _sz) {
    myStep = _st;
    mySz = _sz;
    myX = width/2;
    myY = height/2;
  }
  //Aqui .. no hay "draw", tenemos que crear una funcion de ejecucion 

  void run() {
    updatePosition();
    drawMe();
  }
  void updatePosition() {
    //creamos un random para cada direccion:
    float randX = random(100);
    float randY = random(100);
    //en la X, si es mayor a 50, el walker va para la derecha
    if (randX >= 50) {
      //ve hacia la derecha
      myX += myStep;
    } // y si es menor, para la izquierda
    else {
      myX -= myStep;
    }
    //y lo mismo para Y: si es mayor a 50, el walker va para abajo
    if (randY >= 50) {
      //ve hacia abajo
      myY += myStep;
    } // y si es menor, para arriba
    else {
      myY -= myStep;
    }
    //y finalmente, mantenemos el walker dentro de la ventana con constrin
    myX = constrain(myX, 0, width);
    myY = constrain(myY, 0, height);
  }
  void drawMe() {
    //preparamos color
    //noStroke();
    stroke(64,0,0);
    fill(255, 0, 64);
    //dibujamos:
    ellipse(myX, myY, mySz, mySz);
  }
}


CLASES
 //guardamos el siguiente código como pelota.
class Pelota {
  int x, y;
  color c;

  Pelota() {
    x = int(random(0, width));
    y = int(random(0, height));
    c =color (int(random(0, 255)), int(random(0, 255)), int(random(0, 255)));
  }
 
  void pintar(){
    fill(c);
    ellipse(x,y,20,20);
  }
}


 //guardamos el siguiente código como prueba y lo ejecutamos.
 Pelota p1, p2;
void setup() {
  size(800, 600);
    p1 = new Pelota();
  p2 = new Pelota();
}
void draw() {
  background(0);
  p1.pintar();
  p2.pintar();
}






CREAR UNA BARRA DE 
Processing es un lenguaje válido para casi cualquier cosa aunque se le suele mencionar la pega de que no es adecuado para hacer GUI’s (Graphical User  Interface o interfaz gráfica de usuario), una vez oí esa pega acompañada de un “salen muy feas”. Está claro que si tratamos de crear elementos gráficos como botones o barras de desplazamiento con las primitivas gráficas de Processing van a salir, en el mejor de los casos, muy espartanas… pero ¿y si utilizamos imágenes?. Processing tiene la capacidad de cargar imágenes para utilizarlas dentro de nuestra aplicación sin prácticamente límites y eso nos brinda la oportunidad de darle a nuestros programas un aspecto todo lo elaborado que queramos.
Como ejemplo he programado una ScrollBar muy sencilla con elementos que he sacado de una búsqueda en las imágenes de Google, no voy a poner el código como en otros tutoriales pero lo podéis descargar un poco más adelante. Voy a comentar como lo he hecho y si abrís el código lo encontraréis lleno de comentarios para hacerlo comprensible.
Podéis descargar el proyecto desde aquí.
En la carpeta del proyecto, dentro de la carpeta Data, están las imágenes que lo forman. Básicamente son los extremos derecho e izquierdo (que también funcionan como botones), el cursor y una imagen de 1 píxel de ancho con la que se forma el cuerpo de la barra.
El programa carga las imágenes en variables y luego simplemente las posiciona dentro del canvas todas juntas, el cuerpo de la barra se hace con un bucle for()…. aunque lo podría haber hecho de una sola vez con una imagen más ancha, para gustos colores. Como las imágenes tienen un tamaño de 20×20 píxeles los extremos y 20×30 píxeles el cursor ha habido que hacer un poco de mágia con las coordenadas, pero todo responde a la posición que ocupa cada elemento y el ancho de cada imágen, espero que se entienda bien.
Para dotar de acción a los elementos con los que se pueden interaccionar sólo había que recurrir al truco de concatenar condiciones if() de modo que si esta pulsado el botón del ratón y si esta el ratón dentro de la altura de la imagen y si esta el ratón dentro de la anchura de la imagen se modifica el valor de la variable cursorX , y es esta variable la responsable de almacenar la posición en la que se dibuja el cursor. Lo mismo pasa con los botones laterales, que en un principio iba a dejar sin función por sencillez pero luego pensé que darles funcionalidad era complicar muy poco el código.
El código, tal cual está, se podría utilizar en una aplicación o incluso hacer varias barras iguales y utilizando la misma técnica de utilizar imágenes se pueden añadir otros elementos como botones.



CÓDIGO
/********************************************************

   EJEMPLO DE COMO CREAR UNA BARRA DE DESPLAZAMIENTO
           CON PROCESSING USANDO IMAGENES

*******************************************************/

// Creamos la variables que contendran las imagenes
PImage imagenIzquierda;
PImage imagenCuerpo;
PImage imagenDerecha;
PImage imagenCursor;
// Necesitamos una variable para la posicion del cursor
int cursorX = 200;

void setup()
{
  size(400, 200);
  // Cargamos las imagenes
  imagenIzquierda = loadImage("Izquierda.png");
  imagenCuerpo = loadImage("Cuerpo.png");
  imagenDerecha = loadImage("Derecha.png");
  imagenCursor = loadImage("Cursor.png");
 }

void draw()
{
  // Pintamos un fondo negro
  background(0);
   // Ponemos el extremo izquierdo
  image(imagenIzquierda, 50, 90);
  // Ahora el cuerpo
  for(int i = 70; i <= 329; i++)
    image(imagenCuerpo, i, 90);
  // Por ultimo el extremo derecho
  image(imagenDerecha, 330, 90);
    // si se aprieta el boton del raton y el puntero esta dentro
  // del cursor se actualiza la posicion del cursor
  if (mousePressed)
    if (mouseX > cursorX - 15 && mouseX < cursorX + 15)
      if (mouseY > 80 && mouseY < 100)
        // Ok, podemos actualizar la posicion del cursor
        // pero no podemos pasarnos de los limites
        if (mouseX < 85) cursorX = 85;
        else if (mouseX > 315) cursorX = 315;
             else cursorX = mouseX;
   
    // Vamos a añadir funcionalidad a los botones laterales,
    // primero al izquierdo:
    if(mousePressed)
      if(mouseX > 50 && mouseX < 70)
        if (mouseY > 80 && mouseY < 100)
          cursorX--;
 
    // Y ahora el boton derecho
    if(mousePressed)
      if(mouseX > 330 && mouseX < 350)
        if (mouseY > 80 && mouseY < 100)
          cursorX++;

   // Pintamos el cursor en la posición correcta
   image(imagenCursor, cursorX - 15, 90);
   // Ahora, como curiosidad, escribiremos la posicion del raton
   // encima del cursor
   text(cursorX, cursorX - 10, 80);
}


Ejemplos de juegos con clases:

1) PING PONG http://processing.joan.cat/cs/s10_classes/js/pong/index.html
2) INVASORES DEL ESPACIO http://processing.joan.cat/cs/s10_classes/js/spaceinvaders/index.html