Sequantial Fractal Display confusion

Hello, I have a small error. I think I am in the right direction, but need some guidance. I know this question has been asked, but I can't find an answer that pertains to fractals. I can get it to work with images, but not with recursion. I am trying to get each depth of the fractal to display sequential and delete the previous iteration as it progresses. Hopefully fading as well, but I'm stuck. Thank you in advance.

    //VicsekRecursion
    int num = 5;
    int totalSize = 750;
    color c = 33;
    color first = 255;

    int shape = 0;
    int count = 1;
    int t = 0;

    void setup() {
      size(800, 800);
      rectMode(CENTER);
      noStroke();
    }
////////////////////////////////////////////
    //here is where the error is
    void draw() { 
      if (shape < 6) { 
        fill(lerpColor(first, c, count/60.0f));
        vicsek(width/2, height/2, totalSize, num, c, first);
      }
      if (count++ % 60 == 0) {
        shape++;
        count = 0;
      } else if (t < 100) {
        shape = 0;
        count = 1;
        t = 0;
      }
    }
    //here is where the error ends
  ///////////////////////////////////////////////

    void vicsek(float x, float y, float size, int num, color c, color first) {
      rect(x + size/3, y - size/3, size/3, size/3);
      rect(x - size/3, y - size/3, size/3, size/3);
      rect(x - size/3, y + size/3, size/3, size/3);
      rect(x + size/3, y + size/3, size/3, size/3);

      if (num-- > 1) {
        vicsek(x, y, size/3, num, color(32), color(255)); //center
        vicsek(x, y-size/3, size/3, num, c, first);
        vicsek(x+size/3, y, size/3, num, c, first);
        vicsek(x-size/3, y, size/3, num, c, first);
        vicsek(x, y+size/3, size/3, num, c, first);
      }
    }

Answers

  • edited July 2016

    well t (whatever that stands for) is always < 100 (it's 0), so count doesn't grow (line 28 does always apply?)

    num (the name is pretty bad) is the depth of the recursion; to get different results, change num in line 21.

    Also, lerpcolor needs the smaller amount c first and then the larger amount which you named first (and then amt being the 3rd) I guess or was this intentionally?

    You don't use the colors in the function vicsek.

    //VicsekRecursion
    //int num = 3; //5 
    int totalSize = 750;
    color c = 33;
    color first = 255;
    
    int shape = 1;
    int count =  0;//1
    
    void setup() {
      size(800, 800);
      rectMode(CENTER);
      noStroke();
      // frameRate(12);
    }
    
    void draw() { 
    
      background(255); 
    
      if (shape < 6) { 
        fill(lerpColor(c, first, count/60.0f));
        vicsek(width/2, height/2, totalSize, shape, c, first);
      } 
    
      count++;
    
      if (count % 60 == 0) {
        count = 0;
        shape++;
        if (shape > 6) {
          shape=1;
        }
      }
    }
    
    void vicsek(float x, float y, 
      float size, 
      int num, 
      color c, 
      color first) {
    
      rect(x + size/3, y - size/3, size/3, size/3);
      rect(x - size/3, y - size/3, size/3, size/3);
      rect(x - size/3, y + size/3, size/3, size/3);
      rect(x + size/3, y + size/3, size/3, size/3);
    
      if (num-- > 1) {
        vicsek(x, y, size/3, num, color(32), color(255)); //center
        vicsek(x, y-size/3, size/3, num, c, first);
        vicsek(x+size/3, y, size/3, num, c, first);
        vicsek(x-size/3, y, size/3, num, c, first);
        vicsek(x, y+size/3, size/3, num, c, first);
      }
    }
    
  • edited July 2016

    Precalculate all the lines, store them in a list. Then draw the list a bit at a time.

    edit: having run chrisir's code, do that instead 8)

  • edited July 2016

    Sequential Fractal Display confusion

    Vicsek fractal

    From Wikipedia, the free encyclopedia

    In mathematics the Vicsek fractal, also known as Vicsek snowflake or box fractal, is a fractal arising from a construction similar to that of the Sierpinski carpet, proposed by Tamás Vicsek. It has applications including as compact antennas, particularly in cellular phones.

    https://en.wikipedia.org/wiki/Vicsek_fractal

  • small 3D spin off (non optimized)

    // VicsekRecursion
    // https : // en.wikipedia.org/wiki/Vicsek_fractal
    
    final color RED = color (255, 0, 0); 
    final color GREEN = color (0, 255, 0); 
    final color c = color(2, 2, 255);
    final color first = 255;
    
    final int totalSize = 750;
    
    boolean enableHUD = true; // the text on/off  
    
    int currentDepth =  2; // 1
    float angleRotation;
    float zoomScale1=20.0; 
    
    void setup() {
      size(800, 800, P3D);
      rectMode(CENTER);
      noStroke();
      frameRate(12);
    }
    
    void draw() { 
    
      background(255); 
      if (enableHUD) {
        hint(ENABLE_DEPTH_TEST); // enable Depth Test.
      }
    
      lights(); 
    
      camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0)+zoomScale1, 
        0.0, height/2, 0, 
        0, 1, 0);
    
      rotateY(angleRotation); 
      vicsek(0, height/2, 0, totalSize, currentDepth, c, first);
    
      if (!mousePressed)
        angleRotation+=.014;
    
      // HUD ---------------------------------
    
      if (enableHUD) {
        camera();
        hint(DISABLE_DEPTH_TEST); // Disable Depth Test.
        noLights(); 
        fill(255, 0, 0); 
        text("hit + and - key to change depth ("
          +currentDepth
          +"). Mousewheel to scale ("
          +zoomScale1
          +"). H text on/off.", 
          20, 20);
      }
    }
    
    // -----------------------------------------------------
    
    void keyPressed() {
      switch (key) {
    
        //
      case ' ':
      case '+':
        currentDepth++;
        break; 
    
        //
      case '-':
        currentDepth--;
        break;
    
      case 'H':
      case 'h':
        enableHUD=!enableHUD;
        hint(ENABLE_DEPTH_TEST); // enable Depth Test.
        break; 
    
      default:
        // do nothing 
        break;
      }
    }
    
    
    void mouseWheel(MouseEvent event) {
    
      //This method controls zoomScale1 variable
    
      if (event.getCount()==-1) {
        zoomScale1 += 10;
      } else if (event.getCount()==1) {
        zoomScale1 -= 10;
      }
    
      // check lower boundary 
      //if (zoomScale1<0)
      //  zoomScale1 = 0;
    } 
    
    // the core function 
    void vicsek(float x, float y, float z, 
      float size, 
      int depth, 
      color c, 
      color first) {
    
      fill(c); 
    
      depth--;
    
      float sizeDiv3=size/3; 
    
      if (depth > 1) {
    
        // vicsek(x, y, z, sizeDiv3, depth, c, first); //center
    
        vicsek(x, y-sizeDiv3, z, sizeDiv3, depth, c, first);
        vicsek(x+sizeDiv3, y, z, sizeDiv3, depth, c, first);
        vicsek(x-sizeDiv3, y, z, sizeDiv3, depth, c, first);
        vicsek(x, y+sizeDiv3, z, sizeDiv3, depth, c, first);
    
        vicsek(x, y, z+sizeDiv3, sizeDiv3, depth, RED, first);  
        vicsek(x, y, z-sizeDiv3, sizeDiv3, depth, GREEN, first);
      } else if (depth==1) 
      {
    
        // only depth 1 gets displayed 
    
        box3D(x + sizeDiv3, y - sizeDiv3, z + sizeDiv3, sizeDiv3, c);
        box3D(x - sizeDiv3, y - sizeDiv3, z + sizeDiv3, sizeDiv3, c);
        box3D(x - sizeDiv3, y + sizeDiv3, z + sizeDiv3, sizeDiv3, c);
        box3D(x + sizeDiv3, y + sizeDiv3, z + sizeDiv3, sizeDiv3, c);
    
        box3D(x + sizeDiv3, y - sizeDiv3, z - sizeDiv3, sizeDiv3, c);
        box3D(x - sizeDiv3, y - sizeDiv3, z - sizeDiv3, sizeDiv3, c);
        box3D(x - sizeDiv3, y + sizeDiv3, z - sizeDiv3, sizeDiv3, c);
        box3D(x + sizeDiv3, y + sizeDiv3, z - sizeDiv3, sizeDiv3, c);
      }
    }//func 
    
    // --------------------------------------------------------
    // Misc 
    
    void box3D(float x1, float y1, float z1, 
      float size1, 
      color c1) {
      pushMatrix();
      translate(x1, y1, z1);
      fill(c1); 
      stroke(111);
      //  noStroke(); 
      box(size1); 
      popMatrix();
    } 
    //
    
  • Thank you Chrissir! Very helpful of you and amazing work on the 3D fractal wow :)>- I am working on a version of this which is more object-oriented presently. Thanks for posting the link as well. @Koogs you are right as your approach would be the object oriented one.

    The 3D version kick serious a#@.

    Nevertheless, I am a bit confused still on this section of code:

    if (shape < 6) { 
        fill(lerpColor(c, first, count/60.0f));
        vicsek(width/2, height/2, totalSize, shape, c, first);
      } 
    
      count++;
    
      if (count % 60 == 0) {
        count = 0;
        shape++;
        if (shape > 6) {
          shape=1;
        }
      }
    

    Why is 'count++' variable outside of the brackets and why is 'shape++'' inside the brackets? Thank you again, great work and very helpful. Best, Erik

  • Hey The count variable is within the draw function. The draw function is basically a loop that could be running up to 60fps (frame per second). So what that code does is to execute the change of shape every 60 frames, or every 60 counts. As you see, the count is reset to zero. In fact, because the modulus operator is being used (%), there is no need to reset the counter to zero. This last detail is more of a technicality.

    So in other words, if we assume the computer is running 60 fps, then every second to increase the shape. If the shape exceed the value of 6 then it resets it back to 1. This ensures the shape only has a value of 1 to 6, inclusive.

    I hope this helps,

    Kf

  • Thanks so much kfrajer. Your explanation is very helpful and articulate. Much appreciated!

  • working on the transition a bit.

    Also has a class / objects / OOP now

    //VicsekRecursion
    
    ArrayList<Vicsek> list1 = new ArrayList(); 
    
    void setup() {
      size(800, 800);
      rectMode(CENTER);
      noStroke();
    
      int totalSize = 750;
      color c = 33;
      color first = 255;
    
      for (int shape=1; shape<6; shape++) {
        list1.add(new Vicsek(width/2, height/2, totalSize, shape, c, first));
      }
    }
    
    void draw() { 
      background(255); 
      for (Vicsek cv : list1) {
        cv.vicsekDisplay();
      }
    }
    
    // ==========================================
    
    class Vicsek {
    
      float x;
      float y;
    
      float size;
      int num;
      color c; 
      color first;
    
      int count;
      int countadd=1; 
    
      boolean isAlive=true; 
    
    
      // constr for the class 
      Vicsek(float x_, float y_, 
        float size_, 
        int num_, 
        color c_, 
        color first_) {
    
        x=x_;
        y=y_;
    
        size=size_;
        num=num_;
    
        // negative value!
        // means starting late 
        count = num*-360; 
    
        c=c_;
        first=first_;
      } // constr
    
      void vicsekDisplay() {
    
        if (!isAlive)
          return; 
    
        count+=countadd;
        if (count>255&&countadd>0)
          countadd=-1; 
        if (count<=0 && countadd<0)
          isAlive=false; 
    
        if (count>0)
          vicsek(x, y, size, num, c, first); //center
      }
    
      void vicsek(float x, float y, 
        float size, 
        int num, 
        color c, 
        color first) {
    
        fill(lerpColor(c, first, count));
        fill(0, count); 
    
        rect(x + size/3, y - size/3, size/3, size/3);
        rect(x - size/3, y - size/3, size/3, size/3);
        rect(x - size/3, y + size/3, size/3, size/3);
        rect(x + size/3, y + size/3, size/3, size/3);
    
        if (num-- > 1) {
          vicsek(x, y, size/3, num, color(32), color(255)); //center
          vicsek(x, y-size/3, size/3, num, c, first);
          vicsek(x+size/3, y, size/3, num, c, first);
          vicsek(x-size/3, y, size/3, num, c, first);
          vicsek(x, y+size/3, size/3, num, c, first);
        }
      }
    }
    
  • Thank you @Chrisir. That is an elegant code, but I'm still trying to work up to it. I have gotten this far: Everything is working right, except for the fact that my new generation is erasing the previous one. I am trying to modify this code so that the previous generation remains on the screen.

    Thank you again for the help. =Erik

    ArrayList<Fractal> circle;
    
    void setup() {
      size(500, 500);
    
      //start with one circle
      circle = new ArrayList<Fractal>();
      //pass in the initial constructor
      circle.add(new Fractal(width/2, height/2, 200));
    }
    
    void draw() {
      background(255);
      //show all circles??? with an enhanced forLoop
      for (Fractal f : circle) {
        f.display();
      }
    }
    
    //mousePressed advances the sequence
    void mousePressed() {
      generate();
    }
    
    void generate() {
      //generate next set of circles
      ArrayList<Fractal> next = new ArrayList<Fractal>();
      for (Fractal f : circle) {
        next.add(new Fractal(f.x + f.r/2, f.y, f.r/2));
        next.add(new Fractal(f.x - f.r/2, f.y, f.r/2));
      }
      circle = next;
    }
    
    
    class Fractal {
      float x, y, r;
    
      public Fractal (float x, float y, float r  ) {
        this.x = x;
        this.y = y;
        this.r = r;
      }
    
      void display() {
        stroke(0);
        ellipse(x, y, r, r);
      }
    }
    
  • edited July 2016 Answer ✓
  • Perfect. That does the trick! Gracias.

  • My version has fading

  • The fading is epic. I am attempting to implement the fading into an object-oriented version now.

Sign In or Register to comment.