Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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);
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!!!!
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); }
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); }
} 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); }
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); }
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.
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); }
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; } }
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.
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 }
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
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.
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.
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