simple Squares Recursion Image Processing

edited November 2013 in Questions about Code

Hello...after spending several hours with recursion I've got very confused. What I want to do is to split the image into 4 squares using the color from the center of each square, and make it recursivelly in each square. (Simpler than a quadtree.) However, I was trying to make it animated step by step, or al least level by level.

My code looks like this now and it works but for just one corner,

PImage img;
ArrayList<Square> squares = new ArrayList<Square>();
int tam;

void setup() {
  img = loadImage("http://a4.mzstatic.com/us/r30/Purple/05/81/e6/mzm.kcjwvjip.jpg");
  size(img.width, img.height);
  tam = img.width;
  background(0);
}

void draw() {


  stroke(255, 0, 0);

  if (tam > 2) {
    cuarto(0, 0, tam/2);
    cuarto(0, tam/2, tam/2);
    cuarto(tam/2, 0, tam/2);
    cuarto(tam/2, tam/2, tam/2);

    tam=tam/2;
  }
  for (int i=0; i<squares.size(); i++) {
    squares.get(i).draw();
  }

  noLoop();
}

void mousePressed() {
  redraw();
}

void cuarto(int x, int y, int tam) { 
  squares.add(new Square(x, x, tam, img.pixels[x+tam/2 + (y+tam/2)*img.width]));
}


class Square {
  int x, y;
  int tam;
  color c;

  Square(int _x, int _y, int _tam, color _c) {
    x = _x;
    y = _y;
    tam = _tam;
    c = _c;
  }

  void draw() {
    fill(c);
    rect(x, y, tam, tam);
  }
}

Answers

  • edited November 2013

    Ok, so I got it working. (Level by level)

    I found that I reached the same result as drawing a square tranvering the pixel array followed by a step, what I fool.

    However it would be more interesting to animate the recursion step by step, or try to achive some simple quadtree.

    PImage img;
    ArrayList<Square> squares = new ArrayList<Square>();
    int min = 8; //min size of the square
    
    void setup() {
      img = loadImage("http://a4.mzstatic.com/us/r30/Purple/05/81/e6/mzm.kcjwvjip.jpg");
      size(img.width, img.height);
      background(0);
    }
    
    void draw() {
    
      //stroke(255, 0, 0);
      noStroke();
    
      cuarto(0, 0, img.width);
    
      for (int i=0; i<squares.size(); i++) {
        squares.get(i).draw();
      }
    
      noLoop();
    }
    
    void cuarto(int x, int y, int tam) { 
      if (tam >= min) {
        squares.add(new Square(x, y, tam, img.pixels[x+tam/2 + (y+tam/2)*img.width]));
        cuarto(x, y, tam/2);
        cuarto(x+tam/2, y, tam/2);
        cuarto(x, y+tam/2, tam/2);
        cuarto(x+tam/2, y+tam/2, tam/2);
      }
    }
    
    class Square {
      int x, y;
      int tam;
      color c;
    
      Square(int _x, int _y, int _tam, color _c) {
        x = _x;
        y = _y;
        tam = _tam;
        c = _c;
      }
    
      void draw() {
        fill(c);
        rect(x, y, tam, tam);
      }
    }
    
    void keyPressed() {
      if (key == '-') {
        if (min > 2){
          min = min/2;
        }
      }
      if (key == '+') {
        min = min*2;
      }
      println(key+"..."+min); //min size of the square
      redraw();
    }
    

    EDIT: Animated one by one, http://pastebin.com/CMtfjnZF

  • Answer ✓

    Drawing a recursion process is problematic, because draw() will only draw the final step of function call, and recursive calls only terminates when the recursion reaches its maximum level.

    I saw two approaches to workaround this:

    • Using threads. The recursive function runs in a separate thread, and update the screen at each step, waiting a bit before continuing the next recursive cal. This approach is used / shown in http://forum.processing.org/one/topic/update-screen-from-recursive-function.html for example.
    • Repeating the recursion on each frame, increasing the limit each time. Can be slow when the limit becomes high, needing lot of recursion (and computation) before reaching it.
  • Thanks PhiLho for replying! My last try was adding each square into the arrayList but without drawing them within the recursion. After recursion finishes I would draw them sequencially.

    I'll read about threads. It could be interesting.

Sign In or Register to comment.