logoTh!nk Again


Contemplando las nubes

Posted in Ejemplos by admin on the December 23rd, 2008

El siguiente ejemplo simula el desplazamiento de las nubes. El truco es generar el patrón de nubes y guardarlo en dos imágenes diferentes, la segunda imágen es el espejo vertical de la primera, las “unimos” y tenemos una tira de nubes infinita :P .

float xnoise = 0.0;
PImage []img = new PImage[2];
Timer timer;
int cont;
float ynoise = 0.0;
float inc = 0.01;
int h,w,offset;
void setup(){
  size(300,200);
  timer = new Timer(1);
  timer.start();
  w = width*2;
  cont = 0;
  h = height;
  img[0] = createImage(w,h, ARGB);
  img[1] = createImage(w,h, ARGB);
  offset=-img[0].width;
  for (int x = 0; x < w; x++) {
    int x2 = w-1-x;
    for (int y = 0; y < h ; y++) {     
      float gray = noise(xnoise, ynoise)*255;
      color c = color(map(gray,0,255,0,255),map(gray,0,255,100,255),map(gray,0,255,210,255));
      stroke(c);
      img[0].pixels[y*w + x] = img[1].pixels[y*w  + x2] = c;
      //        point(x, y);
      xnoise = xnoise + inc;

    }
    xnoise = 0;
    ynoise = ynoise + inc;
  }

  stroke(0);
  smooth();
 
}

void draw(){
  background(255);
  if(/*timer.terminado()*/true){
    image(img[(cont==1?1: 0)],offset,0);
    image(img[(cont==1?0 : 1)],offset+img[0].width,0);
    offset+=2;       

    if(offset == 0){
      cont = (cont == 1 ? 0 : 1);
      offset = -img[0].width;
    }

    timer.start();
  }
  noStroke();
  fill(118,16,16);
}


class Timer{
  int t_inicial;
  int lapso;
  Timer(int milisegundos){
    lapso = milisegundos;
  }
  void start(){
    t_inicial = millis();
  }
  boolean terminado(){
    return (millis()-t_inicial >= lapso);     
  }
}

¿Volando con Processing?

Posted in Ejemplos by admin on the December 23rd, 2008

En la siguiente serie de imágenes, hago uso de la función noise() (algoritmo avanzado, desarrollado por Ken Perlin) para generar las nubes y la silueta de las montañas.

float xnoise = 0.0;
float eps=0.04;
Timer timer;
int cont;
float ynoise = 0.0;
float inc = 0.01;
int h,w;
void setup(){
  size(400,250);
  timer = new Timer(1);

  w = width*2;
  cont = 0;
  h = height;

  timer.start();
  stroke(0);
  smooth();


}
void draw_clouds(){
  for (int x = 0; x < w; x++) {
    for (int y = 0; y < h ; y++) {     
      float gray = noise(xnoise, ynoise)*255;
      color c = color(map(gray,0,255,0,255),map(gray,0,255,100,255),map(gray,0,255,210,255));
      stroke(c);
      point(x, y);
      xnoise = xnoise + inc;

    }
    xnoise = 0;
    ynoise = ynoise + inc;
  }
}
void draw_mountains(){
  noStroke();
  fill(168,177,177,124);
  beginShape();
  float y=0,new_y=0;
  vertex(0,height);
  for(int i=4; i<=width; i+=10){
    new_y = height-noise(eps)*200;
    vertex(i,new_y);
    eps+=0.44;
  }
  vertex(width,height);
  endShape(CLOSE);

}
void draw(){ 
  if(timer.terminado()){
    draw_clouds()
    draw_mountains();     
    timer.start();   
  }
}

class Timer{
  int t_inicial;
  int lapso;
  Timer(int milisegundos){
    lapso = milisegundos;
  }
  void start(){
    t_inicial = millis();
  }
  boolean terminado(){
    return (millis()-t_inicial >= lapso);     
  }
}

¿Cómo simular un movimiento natural?

Posted in Challenges, Processing by admin on the December 23rd, 2008

Esto se puede hacer usando un algoritmo aleatorio, que integra processing en la función noise(). ¿podría simular el movimiento de un insecto?

float xtime = 0.0;
float ytime = 100.0;
float increment  = 0.01;
void setup(){
  size(200,200);
  smooth();
  background(255);
}
void draw(){
  if(mousePressed)//limpia la pantalla
    background(255);

  float x = height*noise(xtime);
  float y = width*noise(ytime);
  fill(200);
  ellipse(x,y,10,10);
  ytime+=increment;
  xtime+=increment;
}

Programación Orientada a Objetos

Posted in Ejemplos, Processing by admin on the December 23rd, 2008

El que sigue es un ejemplo clásico, pero ilustra muy bien lo fácil y claro que se vuelve el código cuando usamos programación orientada a objetos (POO). El sketch, dos objetos se mueven de forma aleatoria y los limites de la ventana
son “paredes” que los hacen rebotar. Al “encontrarse”, ambos objetos cambian de color.

El cuerpo del programa “testBall.pde”

// Two ball variables
Ball ball1;
Ball ball2;
void setup() {
  size(400,400);
  smooth();
  // Initialize balls
  ball1 = new Ball(64);
  ball2 = new Ball(32);
}
void draw() {
  background(255);
  // Move and display balls
  ball1.move();
  ball2.move();
  if (ball1.intersect(ball2)) {
    ball1.highlight();
    ball2.highlight();
  }
  ball1.display();
  ball2.display();
}

Definicion de la clase Ball, “Ball.pde”

class Ball{
  float r; // radius
  float x,y;        // location
  float xspeed,yspeed; // speed
  color c = color(100,50);
  // Constructor
  Ball(float tempR) {
    r = tempR;
    x = random(width);
    y = random(height);
    xspeed = random(-5,5);
    yspeed = random(-5,5);
  }
  void move() {
    x += xspeed; // Incrementa x
    y += yspeed; // Incrementa y
    // Check horizontal edges
    if(x > width-r || x < r)
      xspeed*=-1;
    if(y > height-r || y <  r)
      yspeed*=-1;
  }
  void highlight() {
    c = color(0,150);
  }

  // Draw the ball
  void display() {
    noStroke();
    fill(c);
    ellipse(x,y,r*2,r*2);
    c = color(100,50);
  }

  // Una funcion que devuelve falso o verdadero si dos objetos Ball se intersectan
  // Si la distancia entre los radios, es menor que la suma de los radios, entonces hay un contacto
  boolean intersect(Ball b) {
    float distance = dist(x,y,b.x,b.y); // Calculate distance
    return (distance <  r + b.r) ;           // Compare distance to sum of radio
  }
}

Jugando contra reloj: Pucca vs Garu

Posted in Ejemplos, Processing by admin on the December 15th, 2008

En este fin de semana me puse a jugar scrabble y surgió la necesidad de hacer un reloj que controlora los turnos, porque algunos jugadores se tardaban demasiado tiempo en tirar. Funciona como los relojes del ajedrez (solo para dos jugadores).

1. Se establece un tiempo inicial para cada jugador (utilizando el scrollbar, de 1-59 minutos).

2. Después de colocar la palabra, el jugador en turno activa el reloj del jugador contrario y viceversa (presionando cualquier tecla, excepto la ‘p’).

3. El jugador pierde, si su tiempo se agota (su reloj llega a 00:00).

4. Ambos relojes se pausan al presionar la tecla ‘p’.

Aquí les dejo unos pantallazos.

pantalla inicial

pantalla inicial

Juego en curso

Juego en curso

Garu Pierde

Garu Pierde

Pueden bajar la aplicación y el código fuente desde alguno de los siguientes links:

usuarios linux

usuarios windows

Pintando con processing

Posted in Ejemplos, Processing by admin on the December 14th, 2008

En el post introductorio de processing, había mencionado que se trataba de un lenguaje visual, con el cual podemos crear “Arte Visual”, (aunque la categorización de arte es algo subjetivo) aquí les dejo un cuadro “pintado” con processing.

Pueden descargar la aplicación desde aquí:
usuarios linux

usuarios windows

Nota: Debe tener instalado el JRE.

Intersección entre segmentos

Posted in Ejemplos, Processing by admin on the December 6th, 2008

Aquí les dejo un applet que detecta la intersección entre segmentos.



Este es el código fuente, revisen la función intersectan, es la que en realidad hace todo el trabajo :P

/*Geometría computacional
 *por Dennys Regalado Diaz
 *
 *Intersección de Segmentos (02 dic 2008)
 */

segmento new_seg,
         Seg[];
punto anterior;
boolean flag_inter;
int cont,
    num_pts,
    lastX,
    lastY;
color fondo,azul,blanco,opaco;

class punto{
  int x,y;
  punto(){
    x=y=0;
  }
  punto(int new_x,int new_y){
    x= new_x;
    y= new_y;
  }   
}

class segmento{
  punto p0,p1;
  segmento(punto p0,punto p1){
    this.p0 = p0;
    this.p1 = p1;
  }   
}
void setup(){
  Seg = new segmento[1000];
  num_pts = 0;
  cont = 0;
  fondo = color(200,200,196);
  azul = color(13,74,142);
  blanco = color(255);
  opaco = color(179,178,179);
  ///
  size(200,200);
  background(fondo);
  fill(azul)
  smooth();
 
}
double Cross(punto a, punto b,punto c){
  return (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);
}

boolean on_segment(punto a, punto b, punto test){
  return (test.x>=min(a.x,b.x)-6 && test.x<=max(a.x,b.x)+6 &&
    test.y>=min(a.y,b.y)-6 && test.y<=max(a.y,b.y)+6);
}
boolean intersectan(segmento a, segmento b){
  double d1,d2,d3,d4;
  d1 = Cross(b.p0,b.p1,a.p0);
  d2 = Cross(b.p0,b.p1,a.p1);
  d3 = Cross(a.p0,a.p1,b.p0);
  d4 = Cross(a.p0,a.p1,b.p1);
  if(((d1>0 && d2<0) || (d1<0 && d2>0)) &&
    ((d3>0 && d4<0) || (d3<0 && d4>0)))
    return true;

  if(d1==0 && on_segment(b.p0,b.p1,a.p0))
    return true;
  if(d2==0 && on_segment(b.p0,b.p1,a.p1))
    return true;   
  if(d3==0 && on_segment(a.p0,a.p1,b.p0))
    return true;
  if(d4==0 && on_segment(a.p0,a.p1,b.p1))
    return true;

  return false;
}
void pinta_linea(segmento seg, color borde, color relleno){
    stroke(borde);   
    fill(relleno);     
    ellipse(seg.p0.x,seg.p0.y,6,6);
    ellipse(seg.p1.x,seg.p1.y,6,6);
    stroke(relleno);
    line(seg.p0.x,seg.p0.y,seg.p1.x,seg.p1.y);
}
void draw(){
  new_seg = null;
  if(mousePressed){
    if(mouseButton==LEFT && mouseX!=lastX && mouseY!=lastY) {
    //pinta solo un punto
      stroke(blanco);       
      ellipse(mouseX,mouseY,6,6);
   
      lastX=mouseX; lastY=mouseY;
      num_pts++;   

      punto nuevo = new punto(mouseX,mouseY);
      if(num_pts==2 && anterior!=nuevo){         
        num_pts=0;
        new_seg = new segmento(anterior,nuevo);
        int i;
        flag_inter=false;
        for(i=0; i<cont;i++){
          if((flag_inter=intersectan(new_seg,Seg[i]) )){
            break;
          }
        }
        if(!flag_inter)
          Seg[cont++]=new_seg;
        else{ //opaca linea que intersecto
          pinta_linea(new_seg,fondo,opaco);
          pinta_linea(Seg[i],blanco,azul);//repinta linea intersectada
        }
      }   
      anterior = nuevo;   
    }else if (mouseButton==RIGHT){
      cont=0;
      num_pts=0;
      anterior=null;
      background(fondo);
    }
  }

  if(new_seg!=null && !flag_inter)
    pinta_linea(new_seg,blanco,azul);
}

Rompecabezas con processing

Posted in Ejemplos, Processing by admin on the December 3rd, 2008

Va otro ejemplo con el processing, empleando los callbacks mouseDragged(), mouseReleased() que proporciona processing. Así como el uso de imágenes en diferentes formatos: .jpg, .gif y .png.


Este es mi código

/* Drag & Drop
 * por Dennys Regalado Díaz
 * Rompecabezas (02 dic 2008)
 */

PImage images[][],fondo,grid,banner;
cuadro piezas[];
String path_images ="";
int pos_x,pos_y,dragged_item,grid_x,grid_y;
boolean config_inicial;
float offset;
void setup(){
  images = new PImage[4][4];
  piezas = new cuadro[16];
  for(int i=0; i<4; i++)
    for(int j=0; j<4; j++)
      images[i][j]= loadImage(path_images+"image"+i+j+".jpg");

  fondo = loadImage(path_images+"fondo.jpg");
  grid = loadImage(path_images +"grid.png");
  banner = loadImage(path_images +"banner.png");
  size(420,350);     
  pos_x = 10;
  pos_y = 230;
  config_inicial = true;
  dragged_item = -1;
  grid_x = 10;   grid_y =15;

}
class cuadro{
  int x1,x2,y1,y2;
  int ini_x1,ini_x2,ini_y1,ini_y2;
  cuadro(int x1,int y1,int x2,int y2){
    this.x1 = ini_x1=x1;
    this.y1 = ini_y1=y1;
    this.x2 = ini_x2=x2;
    this.y2 = ini_y2=y2;
  }
  boolean over(int x,int y){
    return (x>=x1 && x<=x2 && y>=y1 && y<=y2);
  }
  void back_to_panel(){
    x1 = ini_x1;
    y1 = ini_y1;
    x2 = ini_x2;
    y2 = ini_y2;
  }
}
void draw(){
  background(fondo);
  //banner
/*  float offsetTarget = map(mouseY, 0, height, -banner.height/2.5, 0);
  offset += (offsetTarget-offset)*0.05;
  tint(188,211,95, 201);
  image(banner, 350, offset);   
  noTint();*/

  //
  int x=pos_x,y=pos_y;
  //load images on panel
  if(config_inicial){
    config_inicial = false;
    for(int i=0;i<16;i++){
      piezas[i] = new cuadro(x,y,x+48,y+48);
      if((i+1)%8==0){
        x = pos_x;
        y +=50;
      }
      else
        x +=50;   
    }
  }

  image(grid,grid_x,grid_y);
  ///
  for(int i=0; i<16; i++)
    image(images[i/4][i%4],piezas[i].x1,piezas[i].y1);
  //    image(images[i%4][i/4],grid_x+6+48*(i/4),grid_y+5+48*(i%4));   
 
}

void mouseDragged(){
 
  for(int i=0; i<16; i++){
    if(dragged_item==i || (dragged_item==-1 && piezas[i].over(mouseX,mouseY) )){

      dragged_item = i;
      piezas[i].x1 = mouseX-24;
      piezas[i].y1 = mouseY-24;
      piezas[i].x2 = mouseX+24;
      piezas[i].y2 = mouseY+24;
      break;
    }
  }
}

void mouseReleased(){
  int minx,miny,maxx,maxy;
  if(dragged_item!=-1){
    minx = grid_x+6+48*(dragged_item%4);
    maxx = minx+48;
    miny = grid_y+5+48*(dragged_item/4);
    maxy = miny+48;
//    println(minx+","+maxx+","+miny+","+maxy);
//    println(mouseX+","+mouseY);
    if(mouseX>=minx && mouseX<=maxx &&
      mouseY>=miny && mouseY<=maxy){
      piezas[dragged_item].x1 = minx;
      piezas[dragged_item].x2 = maxx;
      piezas[dragged_item].y1 = miny;
      piezas[dragged_item].y2 = maxy;
    }
    else{
      piezas[dragged_item].back_to_panel();
    }
    dragged_item = -1;
  }
}

El problema de los APPOs

Posted in Challenges, Ejemplos by admin on the December 1st, 2008

Es bien conocido que hace no más de 2 años los denominados APPOs se apoderaron de la ciudad capital del estado de Oaxaca, y entre otras cosas, colocaron una serie de barricadas por toda la ciudad. La PFP envió algunos helicópteros para sobrevolar la zona y reportar el área total ocupada por estas barricadas. Los agentes solo regresaron con la información de las barricadas mapeadas como coordenadas (x,y). ¿Puedes ayudar a completar la misión?

En el siguiente applet (built with processing :P ), puedes generar una instancia del problema.
1. Con el click izquierdo dibujas los puntos que representan las barricadas.
2. Al presionar el click derecho se muestra el área que debes encontrar.