How to make the sketch restart

edited April 20 in Library Questions

Hi all, I am working on this animation which is triggered by the sound input, every time a certain amplitude is picked up a circle is drawn and it makes the animation start. Now I'd like to make the sketch restart (with nothing being drawn) once the maximum count of circles is reached. Is there a way to do it ?

//The generative design is a variation of the programs presented in the
//Generative Design book by Hartmut Bohnacker, Benedikt Gross, Julia Laub and Claudius Lazzeroni. 
//Starting point: Every time an audio amplitude > of a certain value is detected, 
//a new circle is generated at a random position and with a radius determined by the amplitude.
//It is then determined which of the existing circles lies nearest to the new one.
//In the final step, the new circle joins its closest neighbor via the shortest path.
//This is an example of so-called diffusion limited aggregation algorithm. 


import processing.sound.*;


int maxCount = 10000; //max count of the cirlces
int currentCount = 1;
float[] x = new float[maxCount];
float[] y = new float[maxCount];
float[] r = new float[maxCount]; // radius


Amplitude amp;
AudioIn in;
float ampt;

void setup() {

  fullScreen();
 // size(600,600);
  smooth();


  frameRate(1000);

  // first circle
  x[0] = width/2;
  y[0] = height/2;
  r[0] = ampt * 10;
  //r[0] = 400; 

  amp = new Amplitude(this);
  in = new AudioIn(this, 0);
  in.start();
  amp.input(in);
}


void draw() {

   ampt = amp.analyze();
   println(ampt);
  if (ampt>0.03) { // everytime a sound amplitude bigger than 0.03 is detected, a new ellipse is drawn
  strokeWeight(0.5);
  //noFill();
  background(255);

  // create a radom set of parameters
  float newR = ampt*10; // amplitude controls the radius of the circles being drawn 
  float newX = random(0+newR, width-newR);
  float newY = random(0+newR, height-newR);

  float closestDist = 100000000;
  int closestIndex = 0;
  // which circle is the closest?
  for(int i=0; i < currentCount; i++) {
    float newDist = dist(newX,newY, x[i],y[i]);
    if (newDist < closestDist) {
      closestDist = newDist;
      closestIndex = i; 
    } 
  }

  // aline it to the closest circle outline
  float angle = atan2(newY-y[closestIndex], newX-x[closestIndex]);

  x[currentCount] = x[closestIndex] + cos(angle) * (r[closestIndex]+newR);
  y[currentCount] = y[closestIndex] + sin(angle) * (r[closestIndex]+newR);
  r[currentCount] = newR;
  currentCount++;

  // draw them
  for (int i=0 ; i < currentCount; i++) {
    //fill(50,150);
    fill (0);
    //fill(ampt*500, ampt*200, ampt*200, ampt*300);
    ellipse(x[i],y[i], r[i]*2,r[i]*2);  
  }

  if (currentCount >= maxCount) noLoop();
 }
}

Answers

  • edited April 20 Answer ✓

    There is no command like "restart"

    Hint

    Basically move the stuff that initializes your variables from setup() to a new function init() and call it from setup().

    • init() should also implement some stuff that happens before setup such as currentCount = 1; - without the int obviously.

    Make sure size() or fullscreen() are not called again.

    Just when the condition is met [once the maximum count of circles is reached] call init() (not setup()!) again.

    Best, Chrisir ;-)

  • It worked , thanks!

  • edited April 21

    @Mxrx -- Another way:

    Reset your sketch using this line:

    frameCount = -1;
    

    On the next frame (0) this will rerun setup() instead of calling draw(). All of your initial assignments must be made via setup(), not global assignments.

    An advantage of this method is that any sketch that relies on specific frameCount math will also reset frameCount. (This could also be accomplished using the init() described by @Chrisir above by including frameCount=1 in init().)

    For more details on frameCount=0 rerunning setup, see:

  • Thank you for the suggestions! now that I managed to make it restart, I'd like to make it change color according to the sound amplitude that is picked up. For now I have just managed to make all the circles change color multiplying the amplitude by a random value between 0 and 500 in line 89. But what I actually would like to do is to make only the new circles being drawn be of a certain color without all the other changing. Is there a way to do it? For now my code is this

    //The generative design is a variation of the programs presented in the
    //Generative Design book by Hartmut Bohnacker, Benedikt Gross, Julia Laub and Claudius Lazzeroni. 
    //Starting point: Every time an audio amplitude > of a certain value is detected, 
    //a new circle is generated at a random position and with a radius determined by the amplitude.
    //It is then determined which of the existing circles lies nearest to the new one.
    //In the final step, the new circle joins its closest neighbor via the shortest path.
    //This is an example of so-called diffusion limited aggregation algorithm. 
    
    
    import processing.sound.*;
    
    
    int maxCount = 10000; //max count of the cirlces
    int currentCount = 1;
    float[] x = new float[maxCount];
    float[] y = new float[maxCount];
    float[] r = new float[maxCount]; // radius
    
    
    Amplitude amp;
    AudioIn in;
    float ampt;
    
    void setup() {
    
     // fullScreen();
     size(600,600);
    
      amp = new Amplitude(this);  // Create an Input stream which is routed into the Amplitude analyzer
      in = new AudioIn(this, 0);
    
      in.start();// start the Audio Input
      amp.input(in); // patch the AudioIn
    
      init ();
    }
    
    void init (){
    
      frameRate(240);
       smooth();
    
       currentCount = 1;
    
      // first circle
      x[0] = width/2;
      y[0] = height/2;
      r[0] = ampt * 10;
    
     }
    
    void draw() {
    
       ampt = amp.analyze();
    
      if (ampt>0.03) { // everytime a sound amplitude bigger than 0.03 is detected, a new ellipse is drawn
      println (ampt);
      strokeWeight(0.5);
      background(255);
    
      // create a radom set of parameters
      float newR = ampt*10; // amplitude controls the radius of the circles being drawn 
      float newX = random(0+newR, width-newR);
      float newY = random(0+newR, height-newR);
    
      float closestDist = 100000000;
      int closestIndex = 0;
      // which circle is the closest?
      for(int i=0; i < currentCount; i++) {
        float newDist = dist(newX,newY, x[i],y[i]);
        if (newDist < closestDist) {
          closestDist = newDist;
          closestIndex = i; 
        } 
      }
    
      // aline it to the closest circle outline
      float angle = atan2(newY-y[closestIndex], newX-x[closestIndex]);
    
      x[currentCount] = x[closestIndex] + cos(angle) * (r[closestIndex]+newR);
      y[currentCount] = y[closestIndex] + sin(angle) * (r[closestIndex]+newR);
      r[currentCount] = newR;
      currentCount++;
    
      // draw them
      for (int i=0 ; i < currentCount; i++) {
        //fill(50,150);
       // fill (0);
        fill(ampt*random(500), ampt*random(500), ampt*random(500)); // make the color change according to amplitude which is multiplied by a random value between 0 and 500
        ellipse(x[i],y[i], r[i]*2,r[i]*2);  
      }
    
      if (currentCount >= maxCount) init(); // once the maxcount of circles is reached, restart the sketch
     }
    }
    
  • edited April 25 Answer ✓

    @Mxrx --

    only the new circles being drawn be of a certain color without all the other changing. Is there a way to do it?

    Yes. A simple way is to extend the technique you are already using for location and radius:

    float[] r = new float[maxCount]; // radius
    

    ... and additionally create a global array of colors (or ints):

    color[] c = new color[maxCount];
    

    Then instead of putting your color directly in fill:

    fill(ampt*random(500), ampt*random(500), ampt*random(500));
    

    ...you should calculate and save some value in c[currentCount] and then draw with it:

     fill(c[i]);
    

    Finally, you want to map ampt to a color, consider using colorMode(HSB).

    // forum.processing.org/two/discussion/comment/95863/#Comment_95863
    
    import processing.sound.*;
    
    int maxCount = 1000; //max count of the circles
    int currentCount = 1;
    float[] x = new float[maxCount];
    float[] y = new float[maxCount];
    float[] r = new float[maxCount]; // radius
    color[] c = new color[maxCount];
    
    Amplitude amp;
    AudioIn in;
    float ampt;
    
    void setup() {
    
      // fullScreen();
      size(600, 600);
    
      amp = new Amplitude(this);  // Create an Input stream which is routed into the Amplitude analyzer
      in = new AudioIn(this, 0);
    
      in.start();// start the Audio Input
      amp.input(in); // patch the AudioIn
    
      colorMode(HSB, 255, 100, 100);
    
      init ();
    }
    
    void init () {
    
      frameRate(240);
      smooth();
      strokeWeight(0.5);
      currentCount = 1;
    
      // first circle
      x[0] = width/2;
      y[0] = height/2;
      r[0] = ampt * 10;
      c[0] = color(0);
    
      background(255);
    }
    
    void draw() {
    
      ampt = amp.analyze();
      if (ampt>0.03) { // everytime a sound amplitude bigger than 0.03 is detected, a new ellipse is drawn
    
        // create a radom set of parameters
        float newR = ampt*10; // amplitude controls the radius of the circles being drawn 
        float newX = random(0+newR, width-newR);
        float newY = random(0+newR, height-newR);
    
        // which circle is the closest?
        float closestDist = 100000000;
        int closestIndex = 0;
        for (int i=0; i < currentCount; i++) {
          float newDist = dist(newX, newY, x[i], y[i]);
          if (newDist < closestDist) {
            closestDist = newDist;
            closestIndex = i;
          }
        }
    
        // aline it to the closest circle outline
        float angle = atan2(newY-y[closestIndex], newX-x[closestIndex]);
        x[currentCount] = x[closestIndex] + cos(angle) * (r[closestIndex]+newR);
        y[currentCount] = y[closestIndex] + sin(angle) * (r[closestIndex]+newR);
        r[currentCount] = newR;
        c[currentCount] = color(map(ampt*10, 0, 10, 0, 255), 100, 100);
        currentCount++;
    
        // draw them
        for (int i=0; i < currentCount; i++) {
          fill(c[i]); 
          ellipse(x[i], y[i], r[i]*2, r[i]*2);
        }
    
        if (currentCount >= maxCount){
          init(); // once the maxcount of circles is reached, restart the sketch
        }
      }
    }
    

    GrowColorCircles

  • Thank you so much, that's exactly what I was trying to do !

Sign In or Register to comment.