Está en la página 1de 27

Instrucciones de dibujo en 2D con Processing

Pxel | lnea recta | tringulo | crculo/elipse | cuadrado/rectngulo | curva bezier | arco

Pxelset()
Modo de Uso set (x,y,c); Parmetros X x del pixel Y y del pixel C Color. Si se usa un valor entero, se interpreta como valor de gris. Ejemplo cdigo size(150,150); //define el tamao de ventana background(0); //pinta la ventana de negro set(75,75,255); //dibuja un pixel blanco

Lnea Rectaline()
Modo de Uso line (x1,y1,x2,y2); Parmetros x1 x de un extremo y1 y de un extremo x2 x del otro extremo y2 y del otro extremo Ejemplo cdigo size(150,150); //define el tamao de ventana background(255); //pinta el fondo de blanco strokeWeight(4); //ancho de la linea (4 pixeles) line(10,20,130,140);

Tringulotriangle()
Modo de Uso triangle(x1,y1,x2,y2,x3,y3); Parmetros x1 x del primer vrtice y1 y del primer vrtice x2 x del segundo vrtice y2 y del segundo vrtice x3 x del tercer vrtice y3 y del tercer vrtice Ejemplo cdigo size(150,150); //define el tamao de ventana background(255); //pinta el fondo de blanco strokeWeight(4); //ancho de la linea (4 pixeles) triangle(10,110,80,20,130,130);

Crculo / Elipseellipse()
Modo de uso ellipse(x1,y1,x1,y2); Parmetros El uso de los parametros depende de ellipseMode(); ellipseMode(CENTER); (valor por defecto) x1 x del centro y1 y del centro x2 ancho (dimetro) y2 alto (dimetro)

ellipseMode(CORNER); x1 x del vrtice superior izquierdo del rectngulo que la contiene y1 y del vrtice superior izquierdo del rectngulo que la contiene x2 ancho (dimetro) y2 alto (dimetro) ellipseMode(CORNERS); x1 x de un vrtice del rectngulo que la contiene y1 y de un vrtice del rectngulo que la contiene x2 x del vrtice opuesto del rectngulo que la contiene y2 y del vrtice opuesto del rectngulo que la contiene Ejemplo cdigo size(150,150); //define el tamao de ventana background(255); //pinta el fondo de blanco strokeWeight(4); //ancho de la linea (4 pixeles) rectMode(CENTER); //(valor por defecto) ellipse(70,80,130,80);

Cuadrado / Rectngulorectangle()
Modo de uso rect(x1,y1,x1,y2); Parmetros El uso de los parametros depende de rectMode(); rectMode(CENTER); x1 x del centro y1 y del centro x2 ancho y2 alto rectMode(CORNER); (valor por defecto) x1 x del vrtice superior izquierdo y1 y del vrtice superior izquierdo x2 ancho y2 alto rectMode(CORNERS); x1 x de un vrtice y1 y de un vrtice x2 x del vrtice opuesto y2 y del vrtice opuesto Ejemplo cdigo size(150,150); //define el tamao de ventana background(255); //pinta el fondo de blanco strokeWeight(4); //ancho de la linea (4 pixeles) rectMode(CORNER); //modo en que se interpretarn los parmetros en rect() rect(10,10,120,80);

Cuadrilteroquad()
Modo de Uso quad(x1,y1,x2,y2,x3,y3,x4,y4); Parmetros x1 x del primer vrtice y1 y del primer vrtice x2 x del segundo vrtice y2 y del segundo vrtice x3 x del tercer vrtice y3 y del tercer vrtice x4 x del cuarto vrtice y4 y del cuarto vrtice Ejemplo cdigo

size(150,150); //define el tamao de ventana background(255); //pinta la ventana de blanco strokeWeight(4); //ancho de la linea (4 pixeles) quad(20,10,130,30,110,115,40,140);

Curvabezier()
Modo de Uso bezier(x1,y1,x2,y2,x3,y3,x4,y4); Parmetros x1 x de un extremo y1 y de un extremo x2 x del punto de direccin de salida y2 y del punto de direccin de salida x3 x de la direccin de llegada y3 y de la direccin de llegada x4 x del otro extremo y4 y del otro extremo Ejemplo cdigo size(150,150); //define el tamao de ventana background(255); //pinta la ventana de blanco strokeWeight(4); //ancho de la linea (4 pixeles) bezier(20,10,40,140,120,30,110,115);

Arcoarc()
Esta funcin es similar a ellipse, con dos prametro ms para indicar el inicio y el nal del arco que se representar. Modo de uso arc(x1,y1,x1,y2,rad1,rad2); Parmetros El uso de los primeros cuatro parmetros depende de ellipseMode(); En este caso se explican los parmetro con ellipseMode(CENTER); que es el valor por defecto. ver ellipse(); x1 x del centro y1 y del centro x2 ancho (dimetro) y2 alto (dimetro) rad1 punto de inicio rad2 punto de nal Ejemplo cdigo size(150,150); //define el tamao de ventana background(255); //pinta la ventana con colore de fondo blanco strokeWeight(4); //ancho de la linea (4 pixeles) ellipseMode(CENTER); //modo de los parmetros en ellipse() y arc(); arc(80,70,120,80,PI/2,0);

Tipos de datos y operaciones


Introduccin
La programacin trata acerca de la cosbtruccin de algoritmos (conjunto de instrucciones que la computadora deber seguir), durante el desarrollo de dichos algoritmos es necesario establecer algunos datos. Los datos sirven generalmente como parmetros que establecen el grado y forma con el que se ejecutan ciertas instrucciones. Para dar un ejemplo, en el siguiente algoritmo: size(150,150); //define el tamao de ventana background(0); //pinta la ventana de negro set(75,75,255); //dibuja un pixel blanco

todos los nmeros que aparecen (como el 150 en la instruccin size) son datos. En este casos todos los datos que aparecen son constantes, es decir que no cambian su valor durante el transcurso del algoritmo, pero tambin es posible establecer datos variables. Los textos que aparecen en cada lnea despus de la doble barra (//) son comentarios, sirven para que el programador puedo escribir notas para guiarse sin que el compilador las tome como instrucciones,es decir que no son instrucciones ejecutables y el programa las desestima como tales.

Las Variables
Las variables son espacios de memoria que permiten almacenar datos e ir variando sus valores durante el transcurso de un programa. Una variables deber ser declarada para poder ser utilizada, luego se le puedo asignar un valor y ser utilizada: int miVar; //declara una variable numrica llamada "miVar" miVar = 23; //le asigna el valor 23 a la variable miVar println(miVar); //imprime el valor almacenado en miVar. En el ejemplo anterior, en la primer lnea se declar una variable (es decir un espacio de memoria RAM) llamada "miVar", en la segunda lnea se le asign el valor numrico 23, y en la tercer lnea la instruccin println nos permite ver el valor almacenado actualmente en la variable miVar. La instruccin println imprime el valor de variable, as como el resultado de operaciones, en el rea negra de la interface de processing.

Tipos de datos
Los datos que se pueden guardar en variables pueden ser de diferentes tipos, estos tipos responden a la naturaleza de informacin que pueden guardar y operar. Por ejemplo, los dostipos de datos prinicipales son los numrico y los alfanumricos. Los primeros, como su nombre lo indica, almacenan valores numricos, lo que permite realizar operaciones matemticas con ellos, mientras los alfanumrcos almacenan y operan caracteres, es decir letras y otros signos que sirvan para escribir.

Datos numricos
Dentro de los tipos numricos exiten dos tipos principales: los enteros y los reales (con decimales). Los enteros invluyen a los nmeros naturales (que sirven para contar cosas: 1,2,3,...) a los negativos (-1,-2,-3,...) y al cero. Mientras que los reales incluyen a los enteros pero tambin a los nmeros fraccionarios, racionales e irracionales (como la raiz cuadrada de dos o el nmero Pi), es decir todo lo que puede ser representado con decimales (0.14 , 15.67 , -6.8998762 ,etc.). Los enteros se declaran con la palabara int, que viene del trmino ingles integer. Mientras que los reales se declaran con la palabra oat, este trmino viene de la denominacin inglesa de "coma otante" qu es como se llamaba a estos nmeros. As, en el ejemplo que sigue, la primer lnea declara una variable llamada "miVar" de tipo entero, la segunda declara una variable de tipo real llamada "otraVar", la tercer lnea declara 3 variables "a","b" y "c" de tipo entero, y la ltima lnea dos vriables (d y e) de tipo real. int miVar; float otraVar; int a,b,c; float d,e; Cada tipo de dato dene las operaciones que se pueden realizar con dichas variables. Por ejemplo, las variables enteras permiten las 4 operaciones aritmticas bsicas: +,-,*,/ (es decir: suma, resta, multiplicacin y divisin, respectivamente). Si bien la variables de tipo real tambien permite las cuatros operaciones bsicas, una de la diferencias principales es que la divisin es diferente. Por ejemplo, la divisin con datos enteros devuelve valores enteros, mientras que la divisin real devuelve un resultado con decimales. int a,b,e; float c,d,f; a = 10; b = 3; c = 40.0; d = 6.0; println( a / b ); //imprime 3 println( c / d ); //imprime 6.66666666... e = a + b * 8; f = c - d * 2.0;

En este ejemplo, la divisin entre las variables a y b devuelve como resultado un 3 (en vez de 3.3333... que sera el resultado ms preciso), mientras que la divisin entre c y d devuelve 6.6666666.... . En las dos ltimas lneas se puede ver tambin que es posible operar variables entre s y asignar el resultado de dicha operacin a otra variable. El ejemplo que sigue muestra algunas formas abreviadas de escribir ciertas operaciones, como en el caso de a=a+1 que pueden ser escrito como a++: int x,b; x = 100; b = 5; x++; // esto equivale a x=x+1 x--; // esto equivale a x=x-1 x+=b; // esto equivale a x=x+b x-=b; // esto equivale a x=x-b x*=b; // esto equivale a x=x*b x/=b; // esto equivale a x=x/b

Datos alfanumricos
Los datos alfanumricos permiten trabajar con caracteres y cadenas de caracteres (secuencias de caracteres). Los caracteres que la computadora puede utilizar pertenecen al cdigo ASCII (ver el tema en Wikipedia). Los dos tipos de datos alfanumricos que se pueden usar son el tipo caracter y el tipo cadena de caracteres, la diferencia entre estos dos tipos es que el primero slo puede almacenar un caractere mientras que el segundo puede almacenar secuencias y por ende palabras oraciones y cualquier otro tipo de secuencia . Los caracteres se declaran con la palabra char y sus valores constantes se encierran con comillas simples: char miVar; miVar = 'b'; println(miVar); imprime una b Las cadenas de caracteres se declaran con la palabra String y sus valores constantes se encierran entre comillas dobles. La funcin de las comillas en ambos casos es de distinguir los valores alfanumricos del resto del texto del algoritmo. En el ejemplo que sigue se puede ver tambin la nica operacin que permiten los tipos alfanumricos, la concatenacin, que se representa con el signo (+). En la cuarta lnea se puede ver como se le asigna a la variable c la concatenacin de la variable a y la variable b, es decir el valos de la variable a ("hola ") y el valor de la variable b ("mundo!!!!"), lo que sera "hola "+"mundo!!!!": String a,b,c; a = "hola "; b = "mundo!!!!"; c = a + b; println(a); imprime hola println(c); imprime hola mundo!!!!

Otros tipos de datos


Adems de los tipos de datos numricos y alfanumricos, existen otros tipos. Uno de estos, son los datos de tipo lgico, que permiten operar y almacenar valores de verdad lgica. Los datos lgicos pueden adquirir dos valores: verdadero y falso,, que en ingles se escriben: true y false. Estos tipos de datos los veremos ms adelante. Dependiendo del Lenguaje de programacin que se trate, veremos que pueden existir muchos ms tipos de datos primitivos. Por ejemplo en Processing existe el tipo de dato para tratar colores, llamado color.

Interactividad bsica
Los modos esttico y dinmico
Los siguientes ejemplos muestran como trabajar con interactividad en Processing. Este lenguaje permite trabajar e dos modos de programacin, uno esttico y otro dinmico. En el primer modo se escriben las instrucciones en orden descendente pero sin una organizacin externa, mientras que en el segundo modo de programacin el cdigo se organiza en estructuras. Las dos estructuras principales con setup() y draw() (que en versiones anteriores de Processing se llamaba loop() ). En el ejemplo que sigue, las instrucciones que se detallan se ejecutan de arriba a abajo, y el cdigo se ejecuta una nica vez, lo que hace que el algoritmo sirva para generar una nica imagen esttica:

int a; a = 10; size(150,150); background(100); a = (a+1) % 150; rect(a,50,10,10); A diferencia de el anterior ejempo, en el siguiente, las instrucciones mismas instrucciones estan organizadas dentro de la estructura void setup(){ ... } y la estructura void draw(){ ... } . Las instrucciones que se encuentran en el setup() slo se ejecutan una nica vez al inicio del programa. Las instrucciones que se encuentran en el draw() se ejecutan 30 veces por segundo luego de la ejecucin del setup(). Fuera de estas dos estructuras se pueden escribir declaraciones de variables u otras estructuras que luego veremos. int a; void setup(){ a = 10; size(150,150); } void draw(){ background(100); a = (a+1) % 150; rect(a,50,10,10); }

El uso del mouse


Para detectar la posicin del mouse en la pantalla existen dos variables del sistema llamadas mouseX y mouseY. Estas variables representan la posicin horizontal y vertical del mouse, respectivamente. No es necesario declarar estas variables dado que ya pertenecen al sistema. Con el simple hecho de referenciarlas, estas devuelven en cada momento los valores numricos que expresan la posicin del mouse. En los ejemplos siguientes se usan estas variables para dibujar un rectngulo en la posicin del mouse: Ejemplo: Siguiendo el mouse (dejando rastro) int x,y; void setup(){ background(230); //la diferencia esta en esta linea size(200,200); } void draw(){ x=mouseX-25; y=mouseY-25; rect(x,y,50,50); } Ejemplo: Siguiendo el mouse (sin rastro) int x,y; void setup(){ size(200,200); } void draw(){ background(230); //la diferencia esta en esta linea x=mouseX-25; y=mouseY-25; rect(x,y,50,50); }

Otros ejemplos
Ejemplo: Redimensionando el rectngulo con el mouse int x,y; void setup(){ size(200,200); rectMode(CORNER); } void draw(){ background(230); x=mouseX-100; y=mouseY-100; rect(100,100,x,y); }

Ejemplo: Movimiento inverso int x,y; void setup(){ size(200,200); //rectMode(CORNER); } void draw(){ background(230); x=200-mouseX-25; y=200-mouseY-25; rect(x,y,50,50); } Ejemplo: Seguimientos y movimientos inverso int x,y,x1,y1; void setup(){ size(200,200); noFill(); } void draw(){ background(230); x=200-mouseX-25; y=200-mouseY-25; x1=mouseX-25; y1=mouseY-25; rect(x,25,50,50); rect(x1,125,50,50); rect(25,y,50,50); rect(125,y1,50,50); } Ejemplo: Multiplicacin int x,x2,x3,x4,x5,x6; void setup(){ size(600,200); noFill(); } void draw(){ background(230); x=mouseX; x2=x*2; x3=x*3; x4=x*4; x5=x*5; x6=x*6; line(x,0,x,200); line(x2,0,x2,200); line(x3,0,x3,200); line(x4,0,x4,200); line(x5,0,x5,200); line(x6,0,x6,200); }

Ejemplo: Divisin int x,x2,x3,x4,x5,x6; void setup(){ size(600,200); noFill();

} void draw(){ background(230); x=mouseX; x2=x/2; x3=x2/2; x4=x3/2; x5=x4/2; x6=x5/2; line(x,0,x,200); line(x2,0,x2,200); line(x3,0,x3,200); line(x4,0,x4,200); line(x5,0,x5,200); line(x6,0,x6,200); } Ejemplo: Controlando colores con el mouse int x,y,xc,yc; void setup(){ size(255,255); noStroke(); } void draw(){ x=mouseX; y=mouseY; xc=255-x; yc=255-y; fill(x,y,0); rect(0,0,255,255); fill(xc,yc,255); rect(50,50,155,155); }

Estructuras de control condicionales


Estructuras de control
Los ejemplos de los anteriores apartados siguen una lnea nica de ejecucin, es decir, no tienen posibilidad de bifurcar su lnea de ejecucin, ni de repetir ninguna porcin de su cdigo. Para poder dirigir, controlar, la forma en que se ejecuta el algoritmo, es decir, para controlar su ujo de ejecucin, existen dos tipos principales de estructuras: las estructuras condicionales y las estructuras iterativas (repetitivas). Entendemos por estructura a un tipo de demarcacin del cdigo que nos permite organizarlo de alguna forma. En el ejemplo que sigue se ve una estructura condicional que bifurca el cdigo en dos lneas de ejecucin: ... void draw(){ if(mouseX>200){ //comienzo estructura background(255); //primera lnea de ejecucin }else{ //separacin entre las lneas background(0); //segunda lnea de ejecucin } //fin de la estructura } Las estructuras condicionales Las estructuras condicionales permiten bifurcar un algoritmo en funcin de una condicin. Existen diferentes tipos de estructuras condicionales, una de las primeras que veremos es la estructura if-then que se traduce como si-entonces, lo que quiere decir es "si tal cosa entonces hacer tal otra": if( condicin ){ cuerpo de la estructura }

La estructura if-then permite encerrar una porcin de cdigo entre sus dos llaves ( { } ) . Esa porcin de cdigo se ejecuta slo si se cumple la condicin que se encuentra entre los parntesis: void setup(){ size(200,200); } void draw(){ background( 0 ); fill(255); if( mouseX > 100 ){ rect( 50 , 50 , 100 , 100 ); } fill(255,0,0,150); rect(100,0,100,200); }

En el ejemplo de arriba, la instruccin "rect(..." , slo se ejecuta cuando se cumple la condicin "mouseX>200", es decir, se dibuja un rectngulo en la pantalla slo cuando el mouse est ms a la derecha de los 100 pxeles. El segundo rectngulo marca la zona en que la posicin horizontal del mouse supera el valor de 100. A continuacin se puede ver un diagrama de ujo que muestra en qu orden se van ejecutando las instrucciones y bajo qu condiciones: Como muestra el diagrama de arriba el orden en que se ejecutan las instrucciones es: 1ero, se pinta el fondo de negro 2do, se dene el color de relleno en blanco, se pregunta 3ero, se evalua si el mouse supera la posicin horizontal 100 4to, slo si la condicin se cumple se dibuja el cuadrado del centro de color blanco 5to, se dene el color de relleno como rojo con un poco de transparencia 6to, se dibuja un rectngulo del color rojo que muestra el rea activa

La Condicin
En este punto es preciso ver qu es una condicin. Se considera condicin a cualquier variable, constante u operacin que devuelva un valor lgico. Los valores lgicos slo pueden adoptar dos estados: verdadero o falso. En ingls los los valores lgicos verdadero o falso, se escriben true o false respectivamente. Es decir, true o false son las dos nicas constantes lgicas que existen. Una estructura if-then se ejecuta si la condicin devuelve un valor true. En el ejemplo anterior la condicin era una operacin de comparacin ( mouseX > 100 ), las comparaciones dan como resultado un valor de verdad, como muestra el siguiente ejemplo: int a = 10; println( a > 5 ); //esta operacin devuelve el valor true println( a > 15 ); //esta operacin devuelve el valor false

Los comparativos
Los operadores comparativos son los siguientes: println( println( println( println( println( println( 3 2 2 3 2 3 > 2 ); // esto significa 3 es mayor que 2 < 3 ); // esto significa 2 es menor que 3 == 2 ); // esto significa 2 es igual a 2 >= 2 ); // esto significa 3 es mayor o igual que 2 <= 3 ); // esto significa 2 es menor o igual que 3 != 2 ); // esto significa 3 es distinto a 2

En el ejemplo anterior todas las lneas devuelven true. Hay que sealar que el signo de "igual a" se escribe con un doble signo (=), no hay que confundir el (==), que es una comparacin, con el (=), que es una asignacin. En los casos del mayor o igual (>=), la operacin devuelve true tanto en los casos en que el primer valor es mayor al segundo, as como cuando el valor es igual al segundo, es decir que 3>=2 devuelve true y 2==2 tambin devuelve true. El mismo caso se d con el signo menor o igual.

La estructura if-then-else
La estructura if-then, permite ejecutar u omitir una porcin de cdigo en funcin de una condicin. A veces es necesario bifurcar el cdigo en vez de omitirlo. La estructura if-then-else, que se traducira como si-entonces-sino, quiere decir "si tal cosa entonces hacer tal cosa sino hacer tal otra": if( condicin ){ se ejecuta si la condicin es verdadera }else{ se ejecuta si la condicin es falsa } En el ejemplo que sigue, que es una variacin del primer ejemplo, se puede ver como se bifurca el algoritmo a partir de la condicin. Si la condicin ( mouseX > 100 ) se cumple, entonces se dibuja el cuadrado, sino se dibuja el crculo: void setup(){ size(200,200); } void draw(){ background( 0 ); fill(255); if( mouseX > 100 ){ rect( 50 , 50 , 100 , 100 ); }else{ ellipse( 100 , 100 , 100 , 100 ); } fill(255,0,0,150); rect(100,0,100,200); }

La estructura if-then-else if-else


La estructura if-then-else_if-else, permite evaluar varias condiciones para tomar diferentes caminos en funcin de cada una y por ltimo tomar un camino si no se ha cumplido ninguna de estas: if( condicin 1 ){ se ejecuta si la condicin 1 es verdadera }else if( condicin 2 ){ se ejecuta si la condicin 1 es falsa y la 2 es verdadera }else if( condicin 3 ){ se ejecuta si la condicin 1 y 2 son falsas y la 3 es verdadera ... }else{ se ejecuta si todas las condiciones anteriores son falsas } En el ejemplo que sigue, que es una nueva variacin del primer ejemplo, se puede ver como se bifurca dos veces el algoritmo a partir de dos condiciones: void setup(){ size(200,200); } void draw(){ background( 0 ); fill(255); if( mouseX > 100 ){ rect( 50 , 50 , 100 , 100 ); }else if( mouseX > 50 ){ ellipse( 100 , 100 , 100 , 100 ); }else{ triangle(50,150,100,50,150,150); } fill(255,0,0,70); rect(100,0,100,200); rect(50,0,150,200); }

Las variables booleanas


As como existen los valores de verdad true y false, valores lgicos o booleanos (en honor a George Boole ver el tema en Wikipedia), tambin existen variables de tipo lgico. Estas variables se declaran con la palabra boolean y slo pueden adquirir valores booleanos: true o false. Debido a que las comparaciones devuelven valores booleanos, se puede asignar a una variable booleana el resultado de una comparacin: boolean a,b; int c = 10; int d = 20;

a = true; b = c > d; println( a ); //imprime true println( b ); //imprime false En los ejemplos anteriores se podra reemplazar, en la condicin, la operacin de comparacin por una variable booleana: ... boolean a; a = mouseX > 100; if( a ){ En este caso no es muy til, pero existen casos en que se hace necesario cambiar la condicin en forma dinmica.

Las operaciones booleanas


As como cada tipo de dato permite realizar ciertas operaciones, los datos booleanos pueden ser operados por tres operadores llamados: and (que se escribe && ), or (que se escribe || ) y not (que se escribe ! ). Estos operadores sirven para combinar ms de un valor de verdad y obtener uno solo como resultado: println( println( println( println( println( println( println( println( true && true ); //imprime true true && false); //imprime false false && true ); //imprime false false && false); //imprime false true || true ); //imprime true true || false); //imprime true false || true ); //imprime true false || false); //imprime false

println( ! true ); //imprime false println( ! false ); //imprime true Como muestra el ejemplo anterior, el operador and (&&) devuelve un valor true slo cuando los dos operadores son true, caso contrario devuelve false. El operador or (||) devuelve un valor false slo cuando ambos operadores son false, caso contrario devuelve true. Y el operador not (!) invierte el valor de verdad de true a false y viceversa. Estos operadores sirven para evaluar varias comparaciones en una sola condicin, como muestra el ejemplo siguiente, en donde las condicin es cierta cuando se cumplen las dos comparaciones a la vez: cuando mouseX>100 y mouseY>100: void setup(){ size(200,200); } void draw(){ background( 0 ); fill(255); if( mouseX > 100 && mouseY > 100){ //solo se cumple //cuando las dos condiciones son ciertas rect( 50 , 50 , 100 , 100 ); } fill(255,0,0,150); rect(100,100,100,100); } El ejemplo que sigue muestra como se usa el operador or para unir condiciones que no se superponen, dado que alcanza que se de una para ser verdadera: void setup(){ size(200,200); } void draw(){ background( 0 ); fill(255); if( mouseX > 160 || mouseX < 40){ //basta que una de las // dos condiciones sea cierta para cumplirse rect( 50 , 50 , 100 , 100 ); } fill(255,0,0,150); rect(160,0,40,200); rect(0,0,40,200); }

El ejemplo que sigue muestra como el operador not invierte la condicin, haciendo que se cumpla cuando mouseX NO es mayor a 100: void setup(){ size(200,200); } void draw(){ background( 0 ); fill(255); if( !(mouseX > 100) ){ //se cumple si NO es mayor a 100 rect( 50 , 50 , 100 , 100 ); } fill(255,0,0,150); rect(0,0,100,200); }

Estructuras de control condicionales (parte II)


Incrementos cclicos
Hasta aqu hemos visto las estructuras condicionales, ahora veremos una aplicacin de estas estructuras a un problema de incremento con restricciones. Supongamos que tenemos un ejemplo como el que sigue en donde incrementamos una variable para desplazar un objeto en la pantalla: (si el objeto ya salio de pantalla haga click sobre el ejemplo para que vuelva a empezar) int x; void setup(){ size(200,200); smooth(); x = 10; } void draw(){ background(0,0,50); ellipse(x,100,20,20); x++; println(x); } void mousePressed(){ x = 10; } En el ejemplo anterior hemos empleado una estructura void mousePressed(), esta estructura es como setup() o draw(), con la nica diferencia de que esta estructura se ejecuta cuando hacemos click con el mouse. Este ejemplo establece el valor inicial de la variable x en 10, luego en cada fotograma que se ejecuta la estructura draw() la variable x se incrementa en 1. Esto sucede hasta que se termine el programa o el usuario haga click. Es fcil ver que con un algoritmo como este, el valor de x se incrementar hasta el innito (o por lo menos hasta valores muy grandes en funcin de la presicin del lenguaje de prorgramacin), pero en principio esto es un problema dado que si bien queremos que el objeto se desplace no queremos que se vaya de pantalla. La forma de resolver este problema es usando un if-then que nos permita "condicionar" el incremento: int x; void setup(){ size(200,200); smooth(); x = 10; } void draw(){ background(0,0,50); ellipse(x,100,20,20); x++; if( x > width ){ //agregamos esta lnea para condicionar el //incremento x = 0; } } Como se puede ver en este ejemplo, el "if( x > width )" evala si la variable x tiene una valor mayor al ancho de la pantalla (determinado por la variable del sistema llamada width), y si esto es cierto entonces le asigna a x un cero, el equivalente a enviar al objeto al extremo izquierdo de la pantalla. Cabe aclarar que en este ejemplo hubiera sido lo mismo poner "if( x > 200 )" dado que ese es el ancho de la pantalla, pero al usar la variable width nos aseguramos de

que si cambiamos el ancho en algn momento con la instruccin size() entonces no estaremos obligados a buscar los valores del ancho por todo el programa dado que width se acomoda automticamente. El ejemplo que sigue es anlogo al anterior slo que el objeto va de derecha a izquierda y por ende cambia la "condicin de borde", teniendo que evaluar si x es menor a cero, y en caso de ser cierto le asigna el valor width, el equivalente a trasladar al objeto al borde derecho: int x; void setup(){ size(200,200); smooth(); x = 100; } void draw(){ background(0,0,50); ellipse(x,100,20,20); x--; if( x < 0){ x = width; } }

Incremento ida y vuelta


Supongamos ahora que desamos hacer que el objeto vaya ida y vuelta de un extremo al otro. Entonces no encontramos con el problema de que la condicin de borde depende de en qu direccin estamos llendo, pero no slo eso, sino que el incremento tambin depende de la direccin en la que se est moviendo. En el ejemplo que sigue, pusimos una variable que se encarga de sealar la direccin hacia la que nos dirigimos. El crculo comienza en el centro y se aleja hacia la izquierda o derecha en funcin de la variable llamada haciaLaDerecha que es booleana e indica la direccin que sigue el objeto. (si el objeto sale de pantalla haga click con el mouse y el objeto volver al centro de la pantalla y cambiar de direccin) int x; boolean haciaLaDerecha; void setup(){ size(200,200); smooth(); x = width/2; //inicia del centro haciaLaDerecha = true; //establece como direccin la derecha } void draw(){ background(0,0,50); ellipse(x,100,20,20); if( haciaLaDerecha ){ x++; //incrementa si haciaLaDerecha es true } else{ x--; //decrementa si haciaLaDerecha es false } } void mousePressed(){ x=width/2; //si se presiona el mouse vuelve al punto //central y haciaLaDerecha = !haciaLaDerecha; //cambia de direccin } En el ejemplo podemos ver como en funcin de la variable booleana llamada haciaLaDerecha, se produce un incremento (x++) o un decremento (x--). Al presionar el mouse, el objeto vuelve al centro (x=width/2), a la vez que cambia de direccin, dado que la instruccin "haciaLaDerecha = !haciaLaDerecha", cambia el valor de la variable de true a false y viceversa, funciona como un interruptor ON/OFF. Entonces ya que establecimos con la variable haciaLaDerecha la direccin en que se mueve el objeto, entonces ahora podemos hacer que este cambie de direccin cuando este choca el borde: int x; boolean haciaLaDerecha; void setup(){ size(200,200); smooth(); x = width/2; //inicia del centro haciaLaDerecha = true; //establece como direccin la //derecha } void draw(){ background(0,0,50); ellipse(x,100,20,20); if( haciaLaDerecha ){

x++; //incrementa si haciaLaDerecha es true if( x > width ){ //si choca el borde derecha haciaLaDerecha = false; //cambia //de direccin } }else{ x--; //decrementa si haciaLaDerecha es false if( x < 0 ){ //si choca el borde izquierdo haciaLaDerecha = true; //cambia //de direccin } } } Cuando el objeto se dirije hacia la derecha (es decir cuando la variable haciaLaDerecha es true), entonces el borde se evala preguntando si x es mayor que width, mientras que cuendo el objeto se dirije a la izquierda, dicha evaluacin se realiza preguntado si x es menor que cero.

Aprovechando el signo positivo o negativo


El ejemplo que sigue hace lo mismo que el anterior, slo que en vez de tener una variable booleana llamada haciaLaDerecha, tiene una variable entera llamada paso que se encarga de sealar la direccin as como de establecer el incremento o decremento. Veamos cmo hace esto: int x; int paso; void setup(){ size(200,200); smooth(); x = width/2; //inicia del centro paso = 2; } void draw(){ background(0,0,50); ellipse(x,100,20,20); x += paso; //cuando paso es negativo, esto es un //decremento if( x > width || x < 0 ){ //si choca algn borde paso *= -1; //cambia de direccin } } La clave de este programa est en la operacin "x += paso", dado que si paso es positivo (en este caso el valor 2), entonces esta operacin es un incremento (y por ende el objeto se desplaza hacia la derecha), pero cuando paso tiene un valor negativo ( -2 ), entonces esta operacin es un decremento (sumar a un valor otro negativo es el equivalente a restar) y por ende el objeto se dirije a la izquierda. Esta posibilidad del uso del signo para poder realizar decrementos o incrementos con una sola operacin nos permite transformar el cambio de direccin en un cambio de signo, lo que se resuelve en la operacin " paso *= -1", que signica multiplicar a paso por -1 (menos uno). Dado que ambos cambios de direccin son idnticos, entonces podemos evaluar una nica condicin que se ver si x se pas de algn borde (x > width || x < 0).

En dos dimensiones
El ejemplo que sigue traslada estos conceptos de movimiento unidimensional a un movimiento bi-dimensional. Simplemento duplicamos las variables x y paso con otras para el movimiento vertical (y y pasoY), dado que el paso del movimiento vertical se llama pasoY, decid cambiar el nombre de paso por pasoX. Para el lmite vertical usamos la variable de sistema height que es la altura de la pantalla. Note que cambiamos la altura con respecto a la anchura, as como el paso de avance horizontal con respecto al vertical, para mostrar que el ejemplo an funciona: int x,y; int pasoX,pasoY; void setup(){ size(200,300); smooth(); x = 87; y = 13; pasoX = 2; pasoY = 4; } void draw(){ background(0,0,50); ellipse(x,y,20,20); x += pasoX; //movimiento horizontal if( x > width || x < 0 ){ //bordes horizontales pasoX *= -1; //cambia de direccin horizontal

} y += pasoY; //movimiento vertical if( y > height || y < 0 ){ //bordes verticales pasoY *= -1; //cambia de direccin vertical }

Estructuras de control iterativas (repetitivas)


Introduccin
Cuando en un apartado anterior introdujimos el tema de las estructuras de control, se dijo que existan dos tipos principales de estructuras: las condicionales y la iterativas (o repetitivas, que es un sinnimo). Mientras que las estructuras condicionales permiten bufurcar el ujo de ejecucin en funcin de una condicin, las estructuras iterativas permiten repetir una porcin de cdigo en funcin de una condicin.

Los ciclos for-next


La estructura iteartiva ms utilizada es la que se conoce como ciclo for-next. Esta estructura permite repetir, una cantidad determinada de veces, las instrucciones que se encuentran en su interior. Como veremos a continuacin, la estructura posee tre parmetros que son: la inicializacin, la condicin y el incremento: ... for( inicializacion ; condicin ; incremento ){ cuerpo de la estructura } ... Como muestra el esquema anterior, estos tres parmetros van separados por puntos y comas (;) a diferencia de la mayora de las instrucciones en donde los parmetros en que los parmetros van separados por comas (,). En el ejemplo a continuacin se muestra una ciclo for-next utilizado para repetir una instruccin 3 veces: size(200,200); int a = 10; for(int i=0 ; i<3 ; i++){ rect( a , 75 , 50 , 50 ); a += 60; } En el ejemplo anterior, las intrucciones que se encuentran en el interior del ciclo for-next ( "rect( a , 75 , 50 , 50 )" y "a += 60") se repiten 3 veces. Es decir que este programa es el equivalente al que sigue, donde la variable a va adoptando los valores 10,70 y 130, que son las posiciones horizontales de los cuadrados: size(200,200); int a = 10; rect( a , 75 , 50 , 50 ); a += 60; rect( a , 75 , 50 , 50 ); a += 60; rect( a , 75 , 50 , 50 ); a += 60; Cmo es que se produce esta repeticin? Bueno, la forma en que la estructura se ejecuta es la siguiente: Paso 1: en el primer ciclo se ejecuta la inicializacin (en este caso se declara la variable entera llamada i, y se le asigna el valor 0 ) y luego se evalua la condicin (en este caso se evalua si el valor de la variable i es menor a 3) y si se cumple se ejecuta el cuerpo de la estructura . Paso 2: en el siguiente ciclo, ya no se ejecuta la inicializacin, sino que se ejecuta el incremento (en este caso i++, que signica incrementar en 1 el valor de la variable i) y luego se vuelve a evaluar la condicin (nuevamente i<3) y si se cumple la condicin se vuelve a ejecutar el cuerpo del ciclo. Paso 3 al N-simo: a partir de aqu la estructura repite los mismos paso que el paso 2. En el ejemplo anterior, se inicia la variable i en 0 y como cumple la condicin de ser menor a 3 (0 es menor que 3), entonces se ejecuta el cuerpo ( "rect( a , 75 , 50 , 50 )" y "a += 60"), luego se incrementa i (i++) y como i vale 1 y sigue siendo menor a 3, se vuelve a ejecutar el cuerpo, posteriormente vuelve a hacer el incremento y a evaluar la condicin e i que pasa a valer 2 sigue siendo menor que 3, y se vuelve a ejecutar el cuerpo, hasta que en el siguiente incremento i pasa a valer 3 que ya no es menor a 3 (sino igual), y por ende termina el ciclo.

La condicin
En un ciclo for-next es muy importante que la condicin se d al menos una vez, por que sino no se ingresa nunca en el ciclo:

size(200,200); int a = 10; for(int i=4 ; i<3 ; i++){ //esta lnea se modifico poniendo i=4 rect( a , 75 , 50 , 50 ); a += 60; } En el ejemplo anterior se muestra queque la condicin de i<3 nunca se cumplir dado que el valor de i se inicia en 4, por ende nunca se ingresa al ciclo y las instrucciones que est en su interior nunca sern ejecutadas. Tanto la inicializacin, como la condicin y el incremento, son muy exible y permiten utiilizar una gran rango de operaciones y valores. Por ejemplo la inicializacin puede ser con valores distintos de 0 y el incremento puede ser de valores diferentes a 1 , as como otras operaciones metamticas ms all de la suma: for(int i=1 ; i<10 ; println(i); } for(int i=10 ; i>0 ; println(i); } for(int i=1 ; i<=256 println(i); // hasta } i+=2){ //imprime los nmeros impares del 1 al 9 i--){ //este sera un ciclo que decrece desde 10 a 1 ; i*=2){ //en este los valores se duplican desde 1 256, pasando por 2,4,8,16,32,64 y 128

Los bucles innitos


Otro caso importante de tener en cuenta es el caso del bucle innito, en donde la condicin nunca deja de cumplirse y por ende el ciclo nunca termina. Cuando esto sucede, generalmente queda bloqueada la mquina (colgada) y a veces es necesaria apagarla y volver a encenderla: // si no desea colgar su computadora NO EJECUTE ESTE CDIGO for(int i=1 ; i>0 ; i++){ println(i); } Como se puede ver en el caso anterior, la condicin de i>0 se cumple siempre, dado qie i se inicia con el valor 1 y en cada paso se incrementa, pasando por 2, 3, 4, 5, 6, ... y as hasta el innito.

La practicidad de los parmetros


En el primer ejemplo, la variable a que usamos para determinar la ubicacin de los cuadrados, adquiere los valores 10, 60, 130, mientras que la variable del ciclo for-next pasa por los valores 0, 1 y 2. Es posible que la misma variable i del ciclo adopte los valores que necesitamos para ubicar a los cuadrados: size(200,200); for(int i=10 ; i<=130 ; i+=60){ rect( i , 75 , 50 , 50 ); } Esto es posible por que los valores se incrementan en forma ja (saltando de a 60). Cabe aclarar que la variable del ciclo for-next puede tener cualquier nombre.

Los ciclos anidados


Supongamos que queremos hacer un tablero de ajedrez, es decir un tablero de 8x8 cuadros en donde se alternan los cuadros negros y blancos. El primer problema al que nos enfrentamos es el de hacer los 8x8 cuadros, independientemente del color que tengan. Para hacer una nica hilera de cuadrados podemos seguir los ejemplos anteriores: size(200,200); for(int i=0 ; i<8 ; i++){ rect( i * 25 , 0 , 25 , 25 ); } Si quisieramos repetir 8 veces esta hilera modiando su posicin vertical, entonces debemos anidar dos ciclos for-next, haciendo que un nuevo ciclo (exterior al anterior) repita 8 veces las instrucciones necesarias para hacer una hilera: size(200,200); for(int j=0 ; j<8 ; j++){ //este ciclo repite 8 veces al otro ciclo for(int i=0 ; i<8 ; i++){ rect( i * 25 , j * 25 , 25 , 25 ); //aqui se // agrego "j * 25" } }

Queda pendiente la custin de la alternacia entre cuadros negros y blancos. Para estos aprovecharemos una propiedad del table: como muestra la gura siguiente, si sumamos el nmero de la ms el nmero de columna en cada cuadro, notaremos que la alternancia entre resultados pares e impares es equivalente a la de cuadros negros y blancos en una tablero: Por lo que aprovechamos esta propiedad y utilizamos una estructura if-then-else para pintar de negro o blanco en funcin de la paridad de la suma entre el nmero de la y el de columna. En el ejemplo que sigue, el nmero de la es j, mientras que el nmero de columna es i, as que para evaluar si la suma de estos valores es par, vericamos que el resto de dividir dicha suma por 2 sea 0, dado que los nmeros pares devuelven resto 0 al ser divididos por 2. Esto se traduce a preguntar si (i+j) % 2 == 0, dado que el smbolo (%) es el resto de la divisin entera: size(200,200); for(int j=0 ; j<8 ; j++){ for(int i=0 ; i<8 ; i++){ if( (i+j) % 2 == 0 ){ //si la suma //fila+columna es par entonces pinta de negro fill( 0 ); }else{ fill( 255 ); } rect( i * 25 , j * 25 , 25 , 25 ); } } Ejemplo: Estructuras de Control Iterativas: For-Next size(200,200); ellipseMode(CORNER); background(230); for(int a=0;a<200;a+=20){ ellipse(a,a,18,18); } Ejemplo: Estructuras de Control Iterativas: For-Next Anidados size(200,200); ellipseMode(CORNER); background(230); for(int a=0;a<200;a+=20){ for(int b=0;b<200;b+=20){ ellipse(a,b,18,18); } } Ejemplo: Estructuras de Control Iterativas: For-Next Anidados void setup(){ size(200,200); } void draw(){ background(230); for(int i=0;i<=200;i+=20){ for(int j=0;j<=200;j+=20){ line(i,j,mouseX,mouseY); } } }

Ms ejemplos
En los siguientes ejemplos se utilizan ciclos for-next para realizar degrad pintando pixel x pixel. Para eso utiliza una instruccin especial de Processing llamada set( ), que permite establecer el color de un pixel determinado. La instrccin set( ), tiene los siguientes parmetros: set( x , y , color ); size(200,200); color c = color( 255 , 0 , 0 ); set( 10 , 20 , c ); Los dos primeros parmetros son la posicin horizontal y vertical del pixel (x e y) y el tercer parmetro es un color. El color se establece con un tipo de dato color que posee Processing. Una variable de tipo color se declara con la palabra homnima y para asignarle valores es necesario usar la funcin, tambin, color( ), que posee tres parmetros, uno para cada componente color de la paleta RGB (colores primarios de la luz o paleta aditiva del color):

color c; c = color( red , green , blue ); Los valores de cada canal (red, green y blue, que son rojo, verde y azul respectivamente) pueden adoptar valores entre 0 y 255. As, en el ejemplo que sigue se puede ver que conforme la variable i aumenta de 0 a 255 (debido al ciclo fornext), el color rojo aumenta debido a la instruccin que dene el color de los pixeles ( "color c = color(i,0,0)" ), en donde i est puesta en el lugar de la componente roja: size(255,255); for(int i=0 ; i<=255 ; i++){ for(int j=0 ; j<=255 ; j++){ color c = color(i,0,0); set(i,j,c); } } El que sigue es un ejemplo interactivo del anterior slo que fue variado para que el nivel de verde aumentara horizontalmente, el nivel de azul, verticalmente, y el valor de rojo en funcin de la posicin horizontal del mouse. color c; void setup(){ size(255,255); } void draw(){ for(int i=0;i<=255;i++){ for(int j=0;j<=255;j++){ c= color(mouseX,i,j); set(i,j,c); } } } Otro ejemplo, pero en este el fondo y las guras tienen distintos degrad que responden al mouse: color c; void setup(){ size(250,250); noStroke(); ellipseMode(CORNER); } void draw(){ for(int i=0;i<=250;i++){ for(int j=0;j<=250;j++){ c=color(mouseX,i,j); set(i,j,c); } } for(int a=0;a<250;a+=25){ for(int b=0;b<250;b+=25){ c= color(255-mouseX,a,b); fill(c); ellipse(a+2,b+2,20,20); } } } Por ltimo, el ejemplo que sigue aprovecha este recurso expresivo, de variar en forma independiente los degrad de las guras y los fondos, para hacer un modesto homenaje a un gran artista que se llam Victor Vasarely.

El ejemplos que sigue tiene como detalle interesante el hecho de que el lmite del ciclo for-next est determinado por una variable en vez de una cosntante, lo que signica que la cantidad de veces que se repite la estructura vara en cada ejecucin del ciclo. Es importante entender que Processing ejecuta todo el ciclo antes de mostrar el fotograma, recordemos que Processing procesa por defecto 30 fotogramas por segundo, con lo que toda la ejecucindel ciclo se produce con esta tasa. En el ejemplo que sigue, la condicin del ciclo est determinada por una comparacin con mouseX: void setup(){ size(250,250); noStroke(); rectMode(CORNERS); background(0,0,255); } void draw(){ for(int i=0;i<=120 && i< mouseX;i+=10){//en esta lnea se produce la condicin fill(i*2,0,250-i*2); rect(i,i,250-i,250-i); } } Otro ejemplo: int px,py; void setup(){ size(250,250); noStroke(); rectMode(CENTER); background(0,0,255); } void draw(){ for(int i=0;i<=240;i+=10){ px=int(mouseX/250.0*i+(250-i)/2); py=int(mouseY/250.0*i+(250-i)/2); fill(0,i,0); rect(px,py,250-i,250-i); } } El ejemplo que sigue, dibuja una grilla de cuadrados en donde sus tamaos disminuyen conforme aumenta el nmero de la o columna, determinando primero cual de estos dos nmeros es mayor: int mayor; size(400,400); background(0); rectMode(CENTER); noStroke(); for(int i=0 ; i<20 ; i++){ for(int j=0 ; j<20 ; j++){ if(i>j){ mayor=i; }else{ mayor=j; } rect( i*20+10 , j*20+10 , 20-mayor-1 , 20-mayor-1 ); } } El ejemplo que sigue es idntico, pero se diferencia en que es vez de ver cul es mayor de las dos magnitudes (el nmero de la o columna), ve cul es menor: int menor; size(400,400); background(0); rectMode(CENTER); noStroke(); for(int i=0 ; i<20 ; i++){ for(int j=0 ; j<20 ; j++){ if( i<j ){ menor=i; }else{ menor=j; } rect( i*20+10 , j*20+10 , 20-menor-1 , 20-menor-1 ); } }

El ejemplo que sigue es una grilla de crculos en donde su tamao depende de la posicin horizontal del mouse. (Recuerde que algunos navegadores requieren que ud. haga click en el applet para ponerlo en foco y poder interactuar con el mismo): void setup(){ size(400,400); ellipseMode(CENTER); } void draw(){ background(255); fill(0); float ancho=mouseX/5; for(int i=0;i<=400;i+=40){ for(int j=0;j<=400;j+=40){ ellipse(i+20,j+20,ancho,ancho); } } } En el ejemplo que sigue el criterio es similar. El tamao est determinado por la distancia vertical al mouse. Como la posicin vertical del mouse es mouseY y el ciclo que recorre las posiciones verticales de los cculos es j, la distancia vertical est determinada por la operacin: abs(mouseY-j) En donde la funcin abs( ) signica el valor absoluto que es la magnitud de un nmero desprovisto de signo, es decir que el resultado siempre es positivo sin importar de que el signo del resultado de la resta mouseY-j d negativo: void setup(){ size(400,400); ellipseMode(CENTER); } void draw(){ background(255); fill(0); for(int j=0;j<=400;j+=40){ float ancho=abs(mouseY-j)/5; for(int i=0;i<=400;i+=40){ ellipse(i+20,j+20,ancho,ancho); } } }

Nmeros pseudo-aleatorios
El azar y los nmeros pseudo-aleatorios
En la computacin no existen los nmeros al azar dado que la computadoras son mquinas "idealmente" determinista, existen varios factores fsicos que agregan un factor de aleaoriedad a las computadoras, pero en principio las computadoras son deterministas. Debido a esto y a la necesidades que surgen de disponer de valores aleatorios, existen funciones de nmeros pseudo-aleatorios que nos permiten escapar del determinismo computacional. Estas funciones son capaces de generar secuencias de nmeros con patrones anlogos a los nmeros aleatorios. En Processing la funcin que permite generar nmeros pseudo-aleatorios se llama random( ) y puede usar uno o dos parmetros. Si usa uno, la funcin arroja nmeros cada vez que se la invoca, restringiendo estos valores entre cero y el valor del parmetros. En el ejemplo siguiente la funcin random( ) arroja valores entre 0 y 10: void setup(){ } void draw(){ float a = random(10); println( a ); } Estos valores pueden ser utilizados para obtener parmetros como la posicin de un rectngulo en la pantalla: void setup(){ size(200,200); background(0); fill(100,100,255,100); } void draw(){ rect( random(width) , random(height) , 20 , 20 ); } void mousePressed(){ background(0); }

En este ejemplo las funciones random(width) y random(height) devuelven valores pseudo-aleatorios para la posicin horizontal (entre cero y el ancho de la pantalla) y para la posicin vertical (entre cero y el alto de la pantalla). Mientras no se presione el mouse, el draw( ) acumula cuadrados en la pantalla.

Lmite superior e inferior


Tambim es posible restringir el lmite inferior y superior de la funcin random( ) usando dos parmetros: En el ejemplo que sigue, la funcin random(10,20) devuelve valores pseudo-aleatorios entre 10 y 20: void setup(){ } void draw(){ float a = random(10,20); println( a ); } Esto es til en casos como el del ejemplo que sigue, en el que queremos que los nmeros de la secuencia ronden por las valores de la posicin horizontal y vertical del mouse: int col; void setup(){ size(400,400); background(0); colorMode(HSB); col = 0; } void draw(){ col = (col+1) % 256; fill(col,255,255,100); ellipse( random(mouseX-30, mouseX+30) ,random(mouseY-30,mouseY+30) , 20 , 20 ); } void mousePressed(){ background(0); } En este ejemplo las funciones random( mouseX-30 , mouseX+30 ) y random( mouseY-30 , mouseY+30 ) devuelven valores al pseudo-aleatorios dentro de los un rango de 30 pxeles verticales y horizontales del mouse. Cuando se presiona el botn, se ejecuta el background(0) que pinta el fondo de negro. La forma en que se suceden cclicamente los colores es por el uso de la paleta HSB, Processing permite usar esta paleta cuya sigla signica Hue, Saturation y Brightness (Tinte, Saturacin y Brillo). Con la instruccin colorMode(HSB) se determina que se usara la paleta HSB (caso contrario sera colorMode(RGB) para la paleta RGB). Usando esta paleta las instrucciones de pintado, como ll( ) usan 3 o 4 parmetros: tinte, saturacin, brillo y opacidad (en caso de usar 4 parmetros). As la variable llamada col y que tiene un incremento cclico dada la operacin "col = (col+1) % 256", permite ir cambiando el tinte.

El ruido
El ejemplo que sigue utiliza la funcin random( ) para agregarle ruido de desenfoque a la imagen. Para ello, imprime la imagen pixel por pixel pero el color lo toma de otro pixel ligeramente vecino a este. Para trabajar con los pixeles de la imagen usa un tipo de datos de Processing llamado PImage que permite levantar un jpg. (con la funcin loadImage( ) ), imprimirla en pantalla con la instruccin image( ), as como leer el color de cada uno de sus pxeles con la funcin get( ). El nivel de ruido depende de la posicin vertical del mouse: PImage imagen; // tipo PImage para cargar imgenes void setup(){ size(200,300); imagen = loadImage("rana.jpg"); //carga un jpg background(0); //pinta de negro image(imagen, 0, 0); //imprime la imagen } void draw(){ float des = (height-mouseY) / 20; //determina el nivel de desenfoque en funcin de la posicin vertical del mouse for(int x=0 ; x<200 ; x++){ //recorre horizontalmente for(int y=0 ; y<150 ; y++){ //recorre verticalmente color este; //declara la variable este de tipo color este = imagen.get( x+int( random(-des,des) ) , y+int( random(-des,des) ) ); //toma el color de un pixel con un nivel de desenfoque set( x , y+150 , este ); //imprime el color del pixel tomado } } }

El desenfoque se produce por que en vez de tomar el color del pixel que le corresponde se lo desplaza ligeramente a travs de nmero pseudo-aleatorios, esto sucede en la instruccin: este = imagen.get( x+int( random(-des,des) ) , y+int( random(-des,des) ) ); En donde imagen.get( x , y ) lee el color del pixel x,y. En este caso en vez de x se le pasa como parametro: x+int( random(-des,des) ) Que combina la funcin int( ) que transforma los valores reales de la funcin random( ) en valores enteros. Cuanto ms grande sea el valor de la variable llamada des, mayor ser el desenfoque que produce.

La aleatoriedad como recurso expresivo


El ejemplo que sigue aprovecha el random( ) como un recurso expresivo. En cada vuelta de animacin, elige un pixel al azar de la imagen, captura su color y luego imprime un rectngulo con una tamao decidido al azar y con el mismo color (ms transparente) que el pixel original. Si presiona el mouse el procedimiento se reinicia: PImage imagen; // tipo PImage para cargar imgenes void setup(){ size(400,450); imagen = loadImage("rana.jpg"); //carga un jpg noStroke(); rectMode(CENTER); background(0); //pinta de negro image(imagen, 0, 0); //imprime la imagen } void draw(){ float des = (height-mouseY) / 20; //determina el nivel de desenfoque en funcin de la posicin vertical del mouse color este; //declara la variable este de tipo color int x = int( random(200) ); //toma una posicin horizontal al azar int y = int( random(150) ); //toma una posicin vertical al azar este = imagen.get( x , y ); //toma el color del pixel elegido fill( red(este) , green(este) , blue(este) , 100 ); //usa ese color como relleno dndoles cierta transparencia stroke(este); //usa ese color de contorno float lado = random(3,20); //elige el tamao del cuadrado para pintar el pixel rect( x * 2 , y * 2 +150, lado , lado ); //pinta el pixel duplicando el tamao del dibujo } void mousePressed(){ background(0); //pinta de negro image(imagen, 0, 0); //imprime la imagen }

Arreglos
Introduccin
Como vimos en los apartados anteriores, las estructuras iterativas permiten repetir un proceso una gran cantidad de veces, en contraste, cuando se desea realizar un tratamiento homogneo sobre una gran cantidad de informacin, las variables, como se han visto hasta aqu, son insucientes. Esto es debido a que cuandosi desea repetir un procesos sobre una gran cantidad de variables es necesario recurrir a estas haciendo referencia a diferentes nombres, lo que imposibilita utilizar una estructura repetitiva. Por ejemplo, el siguiente es un programa para realizar un promedio de un alumno: float calificacion1 = 9.5; float calificacion2 = 7; float calificacion3 = 5; float total = 0; int cantidad = 3; total += calificacion1; total += calificacion2; total += calificacion3; float promedio = total/cantidad; Si la cantidad de calicaciones a ser promediadas fuesen muchas (por ejemplo 500) el anterior procedimiento no sera aplicable. En una caso como este sera deseable contar con algn tipo de variable que a partir de un nico identicador

(nombre de la variable) permitiese acceder a gran cantidad de informacin para der el mismo tratamiento a toda esta informacin.

Los arreglos
Los arreglos (ver denicin en wikipedia) son variables que permiten acceder a una gran cantidad a partir de una nico identicador y un ndice. Los arreglos pueden ser de varias dimensiones en funcin de la cantidad de ndices que utilizan. Los arreglos de una dimensin son llamados vectores, los de dos dimensiones se llaman matrices, los de tres o ms dimensiones se llaman tensores. Los arreglos adems de ser inicializados, deben ser dimensionados, asignndoles una extensin, es decir la cantidad de celdas de memoria que utilizar: float[] calificacion; //inicializacion del arreglo calificacion = new float[100]; //dimensin del arreglo calificacion[0] = 9.5; //asignacion de la primer celda calificacion[1] = 7.0; //asignacion de la segunda celda Tambin es posible dimensionar y asignar datos en un mismo paso, como se muestra en el siguiente ejemplo: // inicializacion, dimensin // y asignaciones del arreglo float[] calificacion = { 9.5 , 7 , 6.5 , 8 , 10 }; float total = 0; int cantidad = calificacion.length(); for( int i=0 ; i<cantidad ; i++ ){ total += calificacion[ i ]; } float promedio = total/cantidad; println( "El promedio es " + promedio ); En la tercer lnea del ejemplo anterior, se declara el arreglo al mismo tiempo que se le asignan 5 datos ( 9.5 , 7 , 6.5 , 8 y 10 ) lo que determina la extensin de este arreglo ( 5 ). La funcin length (en la quinta lnea) retorna la cantidad de celdas que tiene el arreglo, en este caso, obviamente 5. Las celdas en el arreglo se numeran desde el ndice 0 (cero) hasta la cantidad menos uno (4 en este caso), que son justamente los valores que adquiere la variable i en el ciclo for.

Un ejemplo interactivo
El ejemplo que sigue permite generar crculos con el mouse, haciendo click en el fondo se genera un nuevo crculo, y cuando se hace click sobre un crculo ya creado, se le modica el color y se lo arrastra. float[] x , y , tinta , radio ; //declaracion de los arreglos // necesarios para dibujar los crculos: la posicin -x,y// el color -la tinta- y el tamao -radioint limite; //variable para definir el limite de los arreglos int cantidad; //variable para contar los circulos void setup(){ size(400,400); // INICIALIZAR LA MEMORIA limite = 50; //se define que la cantidad limite de circulos es de 50 cantidad = 0; //se inicia la cantidad de circulos en cero x = new float[limite]; //declara los arreglos con 50 posiciones de memoria cada uno y = new float[limite]; tinta = new float[limite]; radio = new float[limite]; colorMode(HSB); noStroke(); smooth(); } void draw(){ background(240); if( mousePressed ){ //verifica si se presion el mouse boolean tocoAlguno = false; //se declara esta variable para verificar si el mouse toco // algn crculo // VERIFICA SI SE HIZO CLICK SOBRE UN CRCULO YA EXISTENTE for( int i=0 ; i<cantidad ; i++ ){ //recorre los crculos existentes if( dist( x[i] , y[i] , mouseX , mouseY ) < radio[i] ){ //revisa en cada crculo // para ver si el cursor est dentro del crculo //CAMBIAR EL ASPECTO DEL CRCULO SELECCIONADO x[i] = mouseX; // entonces actualiza la posicin del crculo en funcin del mouse y[i] = mouseY; tinta[i] = ( tinta[i] + 1 ) % 255; // incrementa la tinta tocoAlguno = true; // pone la variable en "true" para especificar que un crculo // fue tocado break; // rompe el ciclo for

} //SI NO TOC NINGN CRCULO if( ! tocoAlguno && cantidad<limite ){ // si no toc ningn crculo // y todava existen lugares pendientes entonces crea uno nuevo //ALMACENAR EN MEMORIA UN NUEVO CRCULO x[cantidad] = mouseX; // crea el crculo en la posicion del mouse y[cantidad] = mouseY; tinta[cantidad] = random(255); // le asigna una tinta al azar radio[cantidad] = random(20,80); // le asigna un tamao al azar cantidad++; // incrementa la cantidad de crculos } } // DIBUJAR LOS CRCULOS ALMACENADOS EN MEMORIA for( int i=0 ; i<cantidad ; i++ ){ // recorre cada crculo creado para dibujarlo fill( tinta[i] , 255 , 255 , 100 ); ellipse( x[i] , y[i] , radio[i]*2 , radio[i]*2 ); } } Para poder realizar esta aplicacin, se necesita algn tipo de memoria que guarde las posiciones, colores y tamaos de cada uno de los crculos que son creados para luego poder dibujarlos en forma actualizada. La estructura general de esta aplicacin en pseudocodigo es la siguiente: void setup(){ Inicializar la memoria } void draw(){ if( mousePressed ){ if( Hizo clik sobre un crculo ya existente ){ Cambiar el aspecto del crculo seleccionado } if( No toco ningn circulo ){ Almacenar en memoria un nuevo crculo } } Dibujar los crculos almacenados en memoria } El esquema anterior no es cdigo ejecutable, sino un esquema que combina cdigo ejecutable y explicaciones literales para mostrar la estructura del programa. Luego veremos que las explicaciones literales sern reemplazadas por cdigo ejecutable, de hecho, en el cdigo fuente del ejemplo hay comentarios que indcan las partes correspondientes a estos literales. Si revisamos con atencin el esquema anterior veremos que la idea es crear y actualizar una memoria donde se almacenan las posiciones, colores y tamao de los crculos que hay en pantalla. Luego un parte de la estructura se encarga de dibujar en cada ciclo del void draw() a los crculos que hay almacenados hasta el momento. Cabe aclarar que la instruccin if( mousePressed ){ est preguntando "si el mouse est siendo precionado", dado que mousePressed es una variable de estado que permite saber si el mouse est siendo presionado o no. Esta variable es boolean y devuelve true cuando el mouse est siendo presionado, y false cuando no lo est. La forma en que se implementa esta memoria es utilizando arreglos. Para la realizacin de esta aplicacin es necesario crear cuatro arreglos que sirven para almacenar la posicin, color y tamao de los crculos. Estos arreglos se declaran fuera del void setup() y del void draw() para que sean globales, es decir, para que puedan ser visto desde cualquier parte del algoritmo. Si por el contrario, fueran declarados dentro de alguna de estas estructuras (por ejemplo el void setup() ) no podran ser accedidos desde fuera de dicha estructura. Tambin se declaran dos variables: limite y cantidad, que son utilizadas para especicar la cantidad lmite de crculos que se pueden crear (imite) y la cantidad creada hasta el momento (cantidad). El cdigo a continuacin es el necesario para inicializar la memoria : float[] x , y , tinta , radio ; int limite; int cantidad; void setup(){ size(400,400); limite = 50; cantidad = 0; x = float[limite]; y = new float[limite]; tinta = new float[limite]; radio = new float[limite]; La variable cantidad funciona de la siguiente manera: cuando inicia la aplicacin la variable tiene valor igual a cero. Cuando el usuario hace click, si no se ha tocado ningn crculo, se genera un nuevo crculo. Se le asigna la posicin tomando las coordenadas del cursor y cargndola en los arreglos x e y. El color y el tamao se establecen asignandoles valores al azar a los arreglos tinta y radio, respectivamente. Cuando el crculo que se agrega es el primero, el valor de

cantidad es cero y por lo tanto los valores del primer crculo se carga en la primer celda de los arreglos, es decir en la que tiene ndice igual a cero. Pero inmediatamente despus se incrementa el valor de de la variable cantidad, esto se hace con dos nes: para registrar la cantidad de crculos almacenados y para saber el siguiente lugar disponible para cargar un crculo. El siguiente cdigo es el que sirve para almacenar en memoria un nuevo crculo : ... if( mousePressed ){ ... if( ! tocoAlguno && cantidad<limite ){ x[cantidad] = mouseX; y[cantidad] = mouseY; tinta[cantidad] = random(255); radio[cantidad] = random(20,80); cantidad++; ... Para ilustrar lo que hace el anterior cdigo, imaginemos el sguiente proceso: cuando la aplicacin se inicia por primera vez, la variable cantidad vale cero y an no fue ingresado ningn dato a los arreglos. El sguiente grco muestra los cuatro arreglos vacios y la variable cantidad con el valor cero:

Cuando el usuario hace click y no se ha tocado ningn crculo, entonces se ingresan los valores de la posicin, color y tamao en los arreglos, usando el valor de cantidad como ndice, es decir se carga el ndice cero de cada uno de los arreglos. Por lo que x[cantidad]=mouseX se traduce como x[0]=mouseX, y se carga el valor de la posicin horizontal del mouse en la primer celda (la celda con ndice cero) de X:

Luego se incrementa en uno a la variable cantidad, por lo que pasa a valor uno. En este momento la variable cantidad indica exactamente la cantidad de datos cargados por arreglo, pero tambin indica el valor del siguiente ndice donde se cargaran los nuevos datos:

Cuando el usuario vuelve a hacer click, vuelve a cargar los datos en el ndice que indica la variable cantidad, pero en este caso x[cantidad]=mouseX se traduce como x[1]=mouseX, dado que ahora el valor de cantidad es uno:

Luego vuelve a incrementar la variable cantidad que pasa a valer dos, y nuevamente muestra la cantidad de datos cargados y el prximo ndice a utilizar. Dado que la variable cantidad sirve para saber, justamente, la cantidad de crculos almacenados hasta el momento, esta informacin es til para recorrer los arreglos con un ciclo for a la hora de imprimir los crculos en pantalla, como muestra el cdigo para dibujar los crculos almacenados en memoria : ... for( int i=0 ; i<cantidad ; i++ ){ fill( tinta[i] , 255 , 255 , 100 ); ellipse( x[i] , y[i] , radio[i]*2 , radio[i]*2 ); } ... En el cdigo anterior la variable que recorre los ndices de los arreglos, es la variable i del ciclo for. En este momento, cmo cantidad vale dos, el ciclo for le asigna a la variable i los valores cero y uno, que son casualmente los ndice que estan cargados en los arreglos. As en la instruccin ellipse( x[i] , y[i] , radio[i]*2 , radio[i]*2 ) la cuando la variable

i vale cero, se traduce como ellipse( x[0] , y[0] , radio[0]*2 , radio[0]*2 ). Y dado que x[0], y[0] y radio[0] valen 56, 108 y 30, respectivamente, entonces la instruccin queda nalmente as: ellipse( 56 , 108 , 30*2 , 30*2). Por ltimo, queda por ver cmo es que se selecciona un crculo ya existente. La forma en que se realiza esto es recorrer uno por uno los crculos y vericar si la distancia entre el mouse y el centro del crculo es menor al radio: Para revisar la distancia, Processing tiene una funcin llamada dist(), a la que se le pasa 4 parmetros que son las posiciones X e Y de los dos puntos entre los que se quiere medir la distancia: As para revisar uno por uno las distancia del mouse a cada uno de los centros de los crculos, se usa un ciclo for que recorre con el ndice i cada uno de los crculo y preguntar por la distancia al mouse: dist( x[i] , y[i] , mouseX , mouseY ) < radio[i] El cdigo que sigue sirve para vericar si hizo clik sobre un crculo ya existente y en caso de ser as, entonces cambiar el aspecto del cculo seleccionado : ... boolean tocoAlguno = false; for( int i=0 ; i<cantidad ; i++ ){ if( dist( x[i] , y[i] , mouseX , mouseY ) < radio[i] ){ x[i] = mouseX; y[i] = mouseY; tinta[i] = ( tinta[i] + 1 ) % 255; tocoAlguno = true; break; } } ... Dado que deseamos modicar un crculo por vez, es necesario cortar el cclo for una vez que se encuentra un cculo. Esto lo hace la instruccin break. Esta instruccin interrumpe el ciclo for, por eso se ejecuta cuando el mouse cae dentro de un crculo y se actualizan los datos del crculo seleccionado. La variable tocoAlguno sirve para vericar si algn crculo fue tocado por el mouse, en principio se le asigna un valor false, que slo es cambiado si alguno de los crculos es tocado, en cuyo caso se le asigna el valor true. Esta variable sirve para la parte que almacenar en memoria un nuevo crculo, dado que slo crea un nuevo crculo si el mouse no toco ninguno de los existentes, esto lo puede preguntar de la siguiente manera: if( ! tocoAlguno ){

Ejemplos
El siguiente ejemplo permite grabar la huella que se deja cuando se mueve el mouse. Para eso usa dos vectores llamados X e Y que son recorridos por dos contadores llamados cont e i, que sirven para mover la cabeza grabadora y la cabeza de reproduccin, respectivamente: boolean grabando; //variable que indica el estado int[] x,y; //vectores donde se cargan las posiciones del mouse int cont,i; int contColor; void setup(){ size(400,400); noStroke(); colorMode(HSB); grabando = false; //se inicia en modo reproduccin x = new int[100000]; y = new int[100000]; cont = 0; i = 0; contColor = 0; } void draw(){ contColor = (contColor+1) % 256; //incrementa cclicamente de 0 a 255 fill(0,0,0,10); //pinta el fondo de color rect(0,0,width,height);//negro transparente fill(contColor,255,255,60); //pone el color de relleno de los crculos grabando = mousePressed; //si el mouse est siendo presionado pasa a modo grabacin if(grabando){

} ellipse(x[i],y[i],50,50); i++; //con esta variable recorre el reproductor if(i>=cont){ i=0; } } El siguiente ejemplo permite dibujar rectnguloas presionando y arrastrando el mouse. int estado,cont; int[] x1=new int[1000]; int[] x2=new int[1000]; int[] y1=new int[1000]; int[] y2=new int[1000]; int actualX1,actualY1; void setup(){ size(400,400); rectMode(CORNERS); estado=0; cont=0; } void draw(){ background(0); stroke(0,255,0); noFill(); rect(375,1,398,25); line(375,1,398,25); line(375,25,398,1); fill(0,255,0,30); for(int i=1;i<=cont;i++){ //imprime todos los rectangulos ya grabados, de color verde rect(x1[i],y1[i],x2[i],y2[i]); } if(estado==1){ //si el botn del mouse est presionado (es decir que est generando un rectangulo) stroke(0,0,255); //pone color rojo para el que se est generando fill(0,0,255,30); rect(actualX1,actualY1,mouseX,mouseY); } } void mousePressed(){ if(mouseX>357 && mouseY<25){//si el mouse fue presionado en el cuadrado de la esquina entonces cont=0; //borra todo estado=0; } else{ estado=1; //cuando se presiona el boton estado pasa a 1 (generacin) actualX1=mouseX; //guarda los datos de la actualY1=mouseY; //primer esquina del rectangulo } } void mouseReleased(){ if(!(mouseX>357 && mouseY<25)){//si el mouse no fue presionado en el cuadrado de la esquina entonces estado=0; cont++; //cuenta un nuevo rectangulo x1[cont]=actualX1; //y agrega el nuevo rectangulo y1[cont]=actualY1; x2[cont]=mouseX; y2[cont]=mouseY; } } //dibuja //el boton de la esquina //superio derecha

ellipse(mouseX,mouseY,10,10); x[cont]=mouseX;//guarda un nuevo dato y[cont]=mouseY; cont++; //incrementa el puntero

También podría gustarte