We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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
There is no command like "restart"
Hint
Basically move the stuff that initializes your variables from
setup()
to a new functioninit()
and call it fromsetup()
.init()
should also implement some stuff that happens before setup such ascurrentCount = 1;
- without theint
obviously.Make sure
size()
orfullscreen()
are not called again.Just when the condition is met [once the maximum count of circles is reached] call
init()
(notsetup()
!) again.Best, Chrisir ;-)
It worked , thanks!
@Mxrx -- Another way:
Reset your sketch using this line:
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
@Mxrx --
Yes. A simple way is to extend the technique you are already using for location and radius:
... and additionally create a global array of colors (or ints):
Then instead of putting your color directly in fill:
...you should calculate and save some value in c[currentCount] and then draw with it:
Finally, you want to map
ampt
to a color, consider using colorMode(HSB).Thank you so much, that's exactly what I was trying to do !