Explosion of particles around circle

edited March 2017 in How To...

Hey does anybody know, how to make an explosion of particles starting at the edge of a circle going to the edges of the screen/ window?

«1

Answers

  • edited March 2017 Answer ✓

    Start positions is at x = rad * cos(theta) and y = rad * sin(theta). Direction is given by: vx = cos(theta) and vy = sin(theta).

    Kf

    int rad=50;    //Main circle
    float minr=5;
    float unitx;
    float unity;
    
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    float dtheta=13; //every 13 degrees
    
    float cTheta  = theta0;  //Current theta    
    float x;
    float y;
    float vel=4;
    
    void setup() {
      size(400, 600); 
      noStroke();
      ellipseMode(RADIUS);
    
      setPositionAndOrientation();
    }
    
    void draw() {
      background(0);
      translate(width/2, height/2);
    
      fill(255);
      ellipse(0, 0, rad, rad);
    
      fill(255, 0, 0);
      ellipse(x, y, minr, minr);
    
      x+=vel*unitx;
      y+=vel*unity;
    
      if ((x> -width/2 && y> -height/2 && x<width/2 && y<height/2)==false) {    
        cTheta+=dtheta;  //Increment to next theta
        setPositionAndOrientation();
      }
    
      if (cTheta>thetaEnd)
        noLoop();  //Stop looping when reaching final angle
    }
    
    void setPositionAndOrientation() {
      unitx=cos(radians(cTheta));
      unity=sin(radians(cTheta));
      x=rad*unitx;
      y=rad*unity;
    }
    
  • you are great! its not exactly what i want, but tomorrow I will see if I can make some adjustments. I've never worked with particles before, but i think there is no other way. All particles (maybe about 1000) should start the same time and fly to the edge of the window.

  • Answer ✓

    That is a demonstration. You need a class to keep track of each particle position and orientation. Then you create an array of this class and you are done. If you are stuck figuring out the rest of the code, ask below. I encourage you to review it and attempt the next part.

    Kf

  • edited March 2017

    Hi kfrajer, I have managed to create a (one) particle class but now I'm stuck again. Edit: Look at next comment

    Particle p;
    
    int rad=50;    //Main circle
    float minr=5;
    float unitx;
    float unity;
    
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    float dtheta=13; //every 13 degrees
    
    float cTheta  = theta0;  //Current theta    
    float x;
    float y;
    float vel=4;
    
    void setup() {
      size(400, 600); 
      noStroke();
      ellipseMode(RADIUS);
    
      setPositionAndOrientation();
    
      p = new Particle(new PVector(x,y));
    
    }
    
    void draw() {
      background(0);
      translate(width/2, height/2);
    
      fill(255);
      ellipse(0, 0, rad, rad);
    
    
      x+=vel*unitx;
      y+=vel*unity;
    
      p.run();
    
      if ((x> -width/2 && y> -height/2 && x<width/2 && y<height/2)==false) {    
        cTheta+=dtheta;  //Increment to next theta
        setPositionAndOrientation();
      }
    
      if (cTheta>thetaEnd)
        noLoop();  //Stop looping when reaching final angle
    }
    
    void setPositionAndOrientation() {
      unitx=cos(radians(cTheta));
      unity=sin(radians(cTheta));
      x=rad*unitx;
      y=rad*unity;
    }
    
    class Particle {
    
    Particle(PVector s) {
      }
    
      void run() {
        fill(255,0,0);
        ellipse(x,y,minr,minr);
      } 
    }
    
  • edited March 2017

    maybe I could create an array, but I don't know how to find out :D code is working for now (but not finished).

    int total = 1000;
    Particle[] parray = new Particle[total];
    
    int rad=50;    //Main circle
    float minr=5;
    float unitx;
    float unity;
    
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    float dtheta=13; //every 13 degrees
    
    float cTheta  = theta0;  //Current theta    
    float x;
    float y;
    float vel=4;
    
    void setup() {
      size(400, 600); 
      noStroke();
      ellipseMode(RADIUS);
    
      setPositionAndOrientation();
    
      for (int i = 0; i < parray.length; i++) {
        parray[i] = new Particle(new PVector(x,y));
      }
    
    }
    
    void draw() {
      background(0);
      translate(width/2, height/2);
    
      fill(255);
      ellipse(0, 0, rad, rad);
    
    
      x+=vel*unitx;
      y+=vel*unity;
    
      for (int i = 0; i < parray.length; i++) {
        Particle p = parray[i];
        p.run();
      }
    
      if ((x> -width/2 && y> -height/2 && x<width/2 && y<height/2)==false) {    
        cTheta+=dtheta;  //Increment to next theta
        setPositionAndOrientation();
      }
    
      if (cTheta>thetaEnd)
        noLoop();  //Stop looping when reaching final angle
    }
    
    void setPositionAndOrientation() {
      unitx=cos(radians(cTheta));
      unity=sin(radians(cTheta));
      x=rad*unitx;
      y=rad*unity;
    }
    
    class Particle {
    
    Particle(PVector s) {
      }
    
      void run() {
        fill(255,0,0);
        ellipse(x,y,minr,minr);
      } 
    }
    
  • Looks like you have a class but there is more work to be done on it. You need to take a step back and reconsider what a class will do for you. When creating a class, you should think as a block of functions that handle all the behavior of a single particle. A particle has a coordinate (your class has it), a particle could have a name or even a color. A particle also have motion. It is intrinsic to the particle. In general terms, motion is defined as position (you need to know where you are at any time) and velocity, which tells where the particle is going and dictate future positions. Think about it. A velocity of zero means a particle's position never changes, it states in the same position.

    I am not sure if you are familiar with vector operations. The processing website has good tutorials and if you want one, I could refer you to one for you to revise. I will write down what I had in mind for a class (Actually I borrow most of it from a previous post).

    Next part is to use an array container or a list to keep track of multiple mini-particles. You will need to init all of them and update/show them at the same time. Last task is, what to do when any of them (and all of them) leaves the sketch boundary.

    Kf

    Particle p;
    int rad=50;    //Main circle
    
    
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    float dtheta=13; //every 13 degrees
    
    float cTheta ;  //Current theta   
    float vel=4;    //Mini-particle speed
    
    void setup() {
      size(400, 600);
      noStroke();
      ellipseMode(RADIUS);
    
      cTheta=theta0;
      float unitx=cos(radians(cTheta));
      float unity=sin(radians(cTheta));
      float x=rad*unitx;
      float y=rad*unity;
    
      p = new Particle(x, y);
      p.vel=new PVector(vel*unitx, vel*unity);
    }
    
    void draw() {
      background(0);
      translate(width/2, height/2);
    
      fill(255);
      ellipse(0, 0, rad, rad);
    
      p.update();
      p.show();
    
      if (p.isInsideBoundaries()==false) {
        println("End of run");
        noLoop();
      }
    }
    
    //NEXT class modified from https://forum.processing.org/two/discussion/21158/where-does-this-code-break-the-coding-train-challenge-24/p1
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
      //float xpos, ypos;
    
      float minr;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
        minr=5;
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        fill(255, 0, 0);  
        ellipse(pos.x, pos.y, minr, minr);
      }
    
      void resetEdges() {
        if (pos.x < -width/2) pos.x = -width/2;
        if (pos.x > width/2) pos.x = width/2;
        if (pos.y < -height/2) pos.y = -height/2;
        if (pos.y > height/2) pos.y = height/2;
      }
    
      boolean isInsideBoundaries() {
        return (pos.x> -width/2 && pos.y> -height/2 && pos.x<width/2 && pos.y<height/2);
      }
    }
    
  • edited March 2017

    okay it seems like I've to read a lot :D can you please just say me, where (in which void) I must put the start positions of lets say 15 particles. On the one hand I think the positions must be coded in the setup void, because the particles need their position only one time, but it's paradox to me. It'd be great, if you could recommend me some tutorials.

  • Answer ✓

    Yes, setup is a good place to init each particle's values. They are really good tutorials in the processing.org website under the tutorials section. I recommend both objects and transformations. Full solution below.

    Kf

    int rad=50;    //Main circle
    
    ArrayList<Particle> pars;
    
    
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    float dtheta=13; //every 13 degrees
    
    float vel=4;    //Mini-particle speed
    
    void setup() {
      size(400, 600);
      noStroke();
      ellipseMode(RADIUS);
    
      pars = new ArrayList<Particle>();
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        float x=rad*unitx;
        float y=rad*unity;
    
    
        Particle p = new Particle(x, y);
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    
    void draw() {
      background(0);
      translate(width/2, height/2);
    
      fill(255);
      ellipse(0, 0, rad, rad);
    
    
      boolean allParticlessLeft=true;
    
      for (Particle p : pars) {
        p.update();
        p.show();
    
        if (p.isInsideBoundaries()==true) {
          allParticlessLeft=false;
        }
      }
    
      if (allParticlessLeft==true) {
        println("End of run");
        noLoop();
      }
    }
    
    //NEXT class modified from <a href="https://forum.processing.org/two/discussion/21158/where-does-this-code-break-the-coding-train-challenge-24/p1" target="_blank" rel="nofollow">https://forum.processing.org/two/discussion/21158/where-does-this-code-break-the-coding-train-challenge-24/p1</a>;
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
      //float xpos, ypos;
    
      float minr;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
        minr=5;
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        fill(255, 0, 0); 
        ellipse(pos.x, pos.y, minr, minr);
      }
    
      void resetEdges() {
        if (pos.x < -width/2) pos.x = -width/2;
        if (pos.x > width/2) pos.x = width/2;
        if (pos.y < -height/2) pos.y = -height/2;
        if (pos.y > height/2) pos.y = height/2;
      }
    
      boolean isInsideBoundaries() {
        return (pos.x> -width/2 && pos.y> -height/2 && pos.x<width/2 && pos.y<height/2);
      }
    }
    
  • edited March 2017

    If I want to speed every second particle up, do I have to write a new particle class and "teach" them the new velocity or is it possible with only one particle class?

    Edit: Solution below

  • Answer ✓

    No need to create a new class. That is the beauty of OOP if you have a proper design. I will check your code in a bit and get back to you.

    Kf

  • edited March 2017

    Okay I think I messed up again :D I'm waiting for your answer and also check by myself.

  • I GOT IT :D

    int rad=50;    //Main circle
    float x;
    float y;
    
    ArrayList<Particle> pars;
    
    
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    float dtheta=600; //every 13 degrees
    
    float vel;    //Mini-particle speed
    
    void setup() {
      size(400, 600);
      noStroke();
      ellipseMode(RADIUS);
    
      pars = new ArrayList<Particle>();
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        x=rad*unitx;
        y=rad*unity;
    
    
        Particle p = new Particle(x, y);
        if (floor(a)%2==0) { 
        vel=2;
        } 
        else { 
        vel=4;
        }
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    
    void draw() {
      background(0);
      translate(width/2, height/2);
    
      fill(255);
      ellipse(0, 0, rad, rad);
    
    
      boolean allParticlessLeft=true;
    
      for (Particle p : pars) {
        p.update();
        p.show();
    
        if (p.isInsideBoundaries()==true) {
          allParticlessLeft=false;
        }
      }
    
      if (allParticlessLeft==true) {
        println("End of run");
        noLoop();
      }
    }
    
    //NEXT class modified from <a href="<a href="https://forum.processing.org/two/discussion/21158/where-does-this-code-break-the-coding-train-challenge-24/p1" target="_blank" rel="nofollow">https://forum.processing.org/two/discussion/21158/where-does-this-code-break-the-coding-train-challenge-24/p1</a>;" target="_blank" rel="nofollow"><a href="https://forum.processing.org/two/discussion/21158/where-does-this-code-break-the-coding-train-challenge-24/p1</a>;" target="_blank" rel="nofollow">https://forum.processing.org/two/discussion/21158/where-does-this-code-break-the-coding-train-challenge-24/p1</a></a>;
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        fill(255, 0, 0); 
        ellipse(pos.x, pos.y, 1, 1);
      }
    
      void resetEdges() {
        if (pos.x < -width/2) pos.x = -width/2;
        if (pos.x > width/2) pos.x = width/2;
        if (pos.y < -height/2) pos.y = -height/2;
        if (pos.y > height/2) pos.y = height/2;
      }
    
      boolean isInsideBoundaries() {
        return (pos.x> -width/2 && pos.y> -height/2 && pos.x<width/2 && pos.y<height/2);
      }
    }
    
  • okay now my next problem is, that I want to reset the particles by mouseclick. I have no idea. #-o

  • Answer ✓

    Try this. You need to modify your setup function and move those lines to a separate function so you can call it any time. Like this:

    void reInitSketch() {
    
      //Remove any mini-particle from the list... if any
      if (pars.length!=0)
        pars.clear();
    
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        float x=rad*unitx;
        float y=rad*unity;
    
    
        Particle p = new Particle(x, y);
        if (floor(a)%2==0) {
          vel=2;
        } else {
          vel=4;
        }
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    

    Now, you call reInitSketch() inside stup() and inside any other event (like mouseClicked()) and you will be able to restart it.

    Kf

  • Sorry for asking that much questions but to sum up: In the end I want that the explosion happens after an event and not instantly after starting. If I call reInitSketch() in void draw I get a "sun" instead of single pixels. I understand why this happens, but I dont know how to fix it (I also don't understand why it must be called once in void setup). And based on your latest comment I don't know what to do with line 4 and 5. The error says "lenght cannot be resolved or is not a field" and I simply just don't get it.

  • Answer ✓

    My bad. Use size() instead of length. I should have checked the reference for this small detail.

    You don't have to use the function in setup. Only in a mouse event if that is only what you want and if tat is the only trigger in your program.

    Kf

  • no problem you are really helpful! why isn't this working?

    int rad=50;    //Main circle
    float x;
    float y;
    
    ArrayList<Particle> pars;
    
    
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    float dtheta=600; //every 13 degrees
    
    float vel;    //Mini-particle speed
    
    void setup() {
      size(400, 600);
      noStroke();
      ellipseMode(RADIUS);
    
      pars = new ArrayList<Particle>();
    }
    
    void draw() {
      background(0);
      translate(width/2, height/2);
    
      fill(255);
      ellipse(0, 0, rad, rad);
    
    
      boolean allParticlessLeft=true;
    
      for (Particle p : pars) {
        p.update();
        p.show();
    
        if (p.isInsideBoundaries()==true) {
          allParticlessLeft=false;
        }
      }
    
      if (allParticlessLeft==true) {
        println("End of run");
        noLoop();
      }
    }
    
    void reInitSketch() {
    
      //Remove any mini-particle from the list... if any
      if (pars.size()!=0){
        pars.clear();
      }
    
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        float x=rad*unitx;
        float y=rad*unity;
    
    
        Particle p = new Particle(x, y);
        if (floor(a)%2==0) {
          vel=2;
        } else {
          vel=4;
        }
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    void mousePressed()
    {
      reInitSketch();
    }
    
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        fill(255, 0, 0);
        strokeWeight(1);
        ellipse(pos.x, pos.y, 1, 1);
      }
    
      void resetEdges() {
        if (pos.x < -width/2) pos.x = -width/2;
        if (pos.x > width/2) pos.x = width/2;
        if (pos.y < -height/2) pos.y = -height/2;
        if (pos.y > height/2) pos.y = height/2;
      }
    
      boolean isInsideBoundaries() {
        return (pos.x> -width/2 && pos.y> -height/2 && pos.x<width/2 && pos.y<height/2);
      }
    }
    
  • Answer ✓

    Remove the reference to noLoop(). This function is telling processing not to run your draw(). But you need this function to run your program. I was using this function to stop your program as an initial concept.

    Kf

  • edited March 2017

    and what to do, if the event is not a single event like mousePressed, but rather e.g. a timer is reached in void draw. As soon as the void, which inits the explosion is reached, there are thousands of particles born. But I just want a single "wave" by reaching the time. I hope you can understand what I want to say :D here my sketch or blueprint or whatever to explain:

    void draw()
    {
         timer reaches point and triggers event
    -> "single explosion"   //in my case e-e-e-e-e-e-e-e-explo-o-o-o-osion
    -> end
    }
    void mousePressed()
    {
       timer set to zero
    }
    

    and so on. I've variated the code many times, but everytime it ended up with the multiple explosion.

  • Answer ✓

    I think I got the idea.

    Kf

    int rad=50;    //Main circle
    float x;
    float y;
    
    ArrayList<Particle> pars;
    
    
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    float dtheta=600; //every 13 degrees
    
    float vel;    //Mini-particle speed
    
    void setup() {
      size(400, 600);
      noStroke();
      ellipseMode(RADIUS);
    
      pars = new ArrayList<Particle>();
    }
    
    int timeDelay=5000; //5000 ms or 5secs
    int triggerTime=0;
    boolean initNow=false;
    
    void draw() {
      background(0);
      translate(width/2, height/2);
    
      fill(255);
      ellipse(0, 0, rad, rad);
      surface.setTitle("Waiting for Trigger");
    
      if (millis()<triggerTime) {
        surface.setTitle("Starting in " +(triggerTime+1000-millis())/1000+" secs");
        return;
      } else {
    
        if (initNow==true) {
          reInitSketch() ;
          initNow=false;
          return;
        }
      }
    
      boolean allParticlessLeft=true;
    
      for (Particle p : pars) {
        p.update();
        p.show();
    
        if (p.isInsideBoundaries()==true) {
          allParticlessLeft=false;
        }
      }
    
      if (allParticlessLeft==true) {
        println("End of run");
        surface.setTitle("Waiting for Trigger");
        //noLoop();
      }
    }
    
    void mouseReleased() {
      triggerTime=millis()+timeDelay;
      initNow=true;
    }
    
    void reInitSketch() {
    
      //Remove any mini-particle from the list... if any
      if (pars.size()!=0) {
        pars.clear();
      }
    
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        float x=rad*unitx;
        float y=rad*unity;
    
    
        Particle p = new Particle(x, y);
        if (floor(a)%2==0) {
          vel=2;
        } else {
          vel=4;
        }
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    
    
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        fill(255, 0, 0);
        strokeWeight(1);
        ellipse(pos.x, pos.y, 1, 1);
      }
    
      void resetEdges() {
        if (pos.x < -width/2) pos.x = -width/2;
        if (pos.x > width/2) pos.x = width/2;
        if (pos.y < -height/2) pos.y = -height/2;
        if (pos.y > height/2) pos.y = height/2;
      }
    
      boolean isInsideBoundaries() {
        return (pos.x> -width/2 && pos.y> -height/2 && pos.x<width/2 && pos.y<height/2);
      }
    }
    
  • edited March 2017

    thank you so much, but it didn't solve my problem. maybe it's easier if I show you my "project". It may be confusing, because it's a bit longer and I'm far away of being a pro, as you might have noticed :D. The main idea is two circles fight each other (like cascaded coin tossing) to a maximum and then there is an explosion. you start/stop by clicking the circle and restart by clicking anywhere around. Hope you can find some time to look at it :) you don't have to hurry, it's my own private project. So here is the "half working" code:

    final int initradius=50;
    final int endradius=250;
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    
    ArrayList<Particle> pars;
    
    int a=initradius;
    int b=initradius;
    int startTime;
    int w=0;  //used like a boolean
    float x;
    float y;
    float z;     //50:50 chance of growing
    float dtheta=400; //every ... degrees
    float vel;
    boolean start=false;
    boolean circleOver = true;
    boolean initNow=false;
    color g=color(0,255,0);
    color r=color(255,0,0);
    color ye=color(255,255,0);
    
    void setup()
    {
      size(320, 560);
      startTime=millis();
      background(0);
      fill(0);
      strokeWeight(3);
      stroke(ye);
      ellipse(width/2, height/2,a,a);
      noFill();
      stroke(200);
      ellipse(width/2,height/2,endradius,endradius);
    
      pars = new ArrayList<Particle>();
    }
    
    void draw() 
    {
      update(mouseX, mouseY);
      if (start)
      {
        z=random(0,1);
        if ((millis() - startTime) >=200 )  //>=1000
        {
          startTime=millis();
          if(z>0.5 && b<endradius)
          {
            if(a<b)
            {
              fill(0);
            }
            else
            {
              noFill();
            }
            a=a+20;
            stroke(g);
            ellipse(width/2,height/2,a,a);
          }
          else
          {
            if(b<a)
            {
              fill(0);
            }
            else
            {
              noFill();
            }
            b=b+20;
            stroke(r);
            ellipse(width/2,height/2,b,b);
          }
        }
        if(a==b)
        {
          stroke(ye);
          ellipse(width/2,height/2,a,a);
        }
    
        if (a>=endradius || b>=endradius)
        {
          initNow=true;
          start=false;
          w=1;
        }
      }
        if (initNow==true) {
          initSketch() ;
          initNow=false;
          return;
        }
          else{
        initNow=false;
    
    }
    
    
        boolean allParticlessLeft=true;
    
        for (Particle p : pars) {
          p.update();
          p.show();
    
          if (p.isInsideBoundaries()==true) {
            allParticlessLeft=false;
          }
        }
    
        if (allParticlessLeft==true) {
          pars.clear();
        }
    
    }
    
    void initSketch() {
    
      //Remove any mini-particle from the list... if any
      if (pars.size()!=0){
       // pars.clear();
      }
    
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        float x=width/2+endradius/2*unitx;
        float y=height/2+endradius/2*unity;
    
    
        Particle p = new Particle(x, y);
        if (floor(a)%2==0) {
          vel=2;
        } else {
          vel=4;
        }
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    
    void mousePressed()
    {
      if(w==0 && circleOver==true)
      {
        start=!start;
      }  
      if(w==0 && circleOver==false)
      {
        start=false;
        w=1;    
      }
      if(w==1)
      {
        background(0);
        strokeWeight(3);
        a=initradius;
        b=initradius;
        stroke(ye);
        ellipse(width/2,height/2,b,b);
        noFill();
        stroke(200);
        ellipse(width/2,height/2,endradius,endradius);
        w=0;
      }
    }
    
    void update(int x, int y) 
    {
      if(overCircle(width/2, height/2, endradius) ) 
      {
        circleOver = true;
      } 
      else 
      {
        circleOver = false;
      }
    }
    
    boolean overCircle(int x, int y, int diameter) 
    {
      float disX = x - mouseX;
      float disY = y - mouseY;
      if(sqrt(sq(disX) + sq(disY)) < diameter/2 ) 
      {
        return true;
      } 
      else 
      {
        return false;
      }
    }
    
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        strokeWeight(1);
        ellipse(pos.x, pos.y, 1, 1);
      }
     /*
      void resetEdges() {
        if (pos.x < -width/2) pos.x = -width/2;
        if (pos.x > width/2) pos.x = width/2;
        if (pos.y < -height/2) pos.y = -height/2;
        if (pos.y > height/2) pos.y = height/2;
      }
     */
      boolean isInsideBoundaries() {
        return (pos.x> 0 && pos.y> 0 && pos.x<width && pos.y<height);
      }
    }
    
  • Oh and I really want to thank you for your support!

  • Answer ✓

    Sorry, not clear what you mean with this:

    like cascaded coin tossing

    Kf

  • edited March 2017

    I described it more difficult as it is. I just wantet to say that there is a 50:50 chance of growing for the red/ green circle. The only problem is that i don't know where to put the initSketch();.

  • Answer ✓

    I looked at your last four posts and my head spins. Sorry, no clue what you mean. From your latest code where you have a functional demo, what should be happening instead? Describe some steps to apply to your sketch and what it is observed vs. what it suppose to be observed.

    Kf

  • okay my latest comment is about my real project, the other explosion thing was to understand how to use particles. then i wanted to integrate this code in my actual project. If you start the code of my latest post and click into the circle you will see two circles grow until they reach the white circle. after they reached it, there should be the expolsion. Well, there is an explosion but you will see, that lots of explosions overlay. so instead of having 9999999 particles I just want these: float dtheta=400; at once. Sorry for the mind twist :D I tried to rearrange the code but its always messed up (the mess happens between line 83 and 99)

    That is the biggest problem. after this is solved I only want, that the particles are reseted and you can begin again.

  • i think line 83 to 99 should stand anywhere else.

  • Answer ✓

    NOTE: Line 187 can be changed to dist(). Check the reference.

    The issue is that you are not calling background(). Introduce background(0) as your first line of draw. Then click in the sketch and let the magic happen. However you need to change your code to show the first part of the interaction as this is not redrawn in every frame as it should (in this case).

    The solution would be:
    1. First line in draw: background
    2. Move line 30-35 to draw right after background
    3. When you draw ellipse a and b, draw them using a for loop instead of only drawing the final position.

    Kf

  • You are my hero! I will fix it this weekend :) can you explain a few more things to me? I've read the reference of some commands but didn't understand the usage: what does "return" do with or without a bracket behind? sooner or later I want to run it on my phone. is there a possibility of getting the screensize? I've read that "size" must be feeded with numbers not variables. As you might have noticed I used w=0 respectively w=1 as a kind of boolean. what is the advantage of a boolean?

  • Answer ✓

    I've read the reference of some commands but didn't understand the usage

    If something isn't clear, post it in the forum and they will clarify it and even suggest to have it fix in the documentation. This input is valuable.

    what does "return" do with or without a bracket behind?

    You will need to show some code to be able to understand your question.

    is there a possibility of getting the screensize? I've read that "size" must be feeded with numbers not variables

    displayWidth,displayHeight for once, or using fullScreen(). You could adjust the size of the screen using variables but this only works if you use settings() before setup(). Check the following links:

    https://processing.org/reference/settings_.html
    https://processing.org/reference/pixelWidth.html
    https://processing.org/reference/return.html

    Kf

  • what does "return" do with or without a bracket behind?

    return doesn't need a bracket but it doesn't matter

    it returns a value in functions that are not empty

    void setup() {
      println( sum (3, 5) );
    }
    
    int sum (int a, int b) {
      return a+b;
    }
    
  • edited March 2017 Answer ✓

    As you might have noticed I used w=0 respectively w=1 as a kind of boolean.

    a boolean can hold only true or false. Thus when w can only have two states, the type boolean describes more precise its purpose than int. So it's better for the reader of your code (or you in a few month)

    Because int can have many states (0,1,2,3.....) and boolean only one.

    boolean is faster and doesn't use as much memory, but this is insignificant.

  • Thanks a lot for your answeres. Now I'm trying to draw the ellipses with a for loop, but I don't know where to put it exactly and what boundaries I should use. Could you please give me a hint before you disclose the hole solution?

  • Answer ✓

    Can you post your code....?

  • final int initradius=50;
    final int endradius=250;
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    
    ArrayList<Particle> pars;
    
    int a=initradius;
    int b=initradius;
    int startTime;
    float x;
    float y;
    float z;
    float dtheta=400; //every ... degrees
    float vel;
    boolean start=false;
    boolean end=false;
    boolean circleOver = true;
    boolean initNow=false;
    color g=color(0,255,0);
    color r=color(255,0,0);
    color ye=color(255,255,0);
    
    void setup()
    {
      size(320, 560);
      startTime=millis();
      background(0);
      fill(0);
      strokeWeight(3);
      stroke(ye);
      ellipse(width/2, height/2,initradius,initradius);
      noFill();
      stroke(200);
      ellipse(width/2,height/2,endradius,endradius);
    
      pars = new ArrayList<Particle>();
    }
    
    void draw() 
    {
      background(0);
      if(start==false && end==false)
      {
        strokeWeight(3);
        stroke(ye);
        ellipse(width/2, height/2,initradius,initradius);
      }
      noFill();
      stroke(200);
      ellipse(width/2,height/2,endradius,endradius);
      clickArea();
      if (start)
      {
        z=random(0,1);
        if ((millis() - startTime) >=200 )  //>=1000
        {
          startTime=millis();
          if(z>=0.5 && b<endradius)
          {
            if(a<b)
            {
              fill(0);
            }
            else
            {
              noFill();
            }
            a=a+20;
            stroke(g);
            ellipse(width/2,height/2,a,a);
          }
          if(z<0.5 && a<endradius)
          {
            if(b<a)
            {
              fill(0);
            }
            else
            {
              noFill();
            }
            b=b+20;
            stroke(r);
            ellipse(width/2,height/2,b,b);
          }
        }
        if(a==b)
        {
          stroke(ye);
          ellipse(width/2,height/2,a,a);
        }
    
        if (a>=endradius || b>=endradius)
        {
          initNow=true;
          start=false;
          end=true;
        }
      }
      if (initNow==true) 
      {
        initSketch() ;
        initNow=false;
        return;
      }
      else
      {
        initNow=false;
      }  
    
      boolean allParticlessLeft=true; 
      for (Particle p : pars)
      {
        p.update();
        p.show();
        if (p.isInsideBoundaries()==true)
        {
          allParticlessLeft=false;
        }
      } 
      if (allParticlessLeft==true) 
      {
        pars.clear();
      }
      strokeWeight(3);
    }
    
    void initSketch()
    { 
      //Remove any mini-particle from the list... if any
      if (pars.size()!=0){
       // pars.clear();
      }
    
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        float x=width/2+endradius/2*unitx;
        float y=height/2+endradius/2*unity;
    
        Particle p = new Particle(x, y);
        if (floor(a)%2==0) {
          vel=2;
        } else {
          vel=4;
        }
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    
    void mousePressed()
    {
      if(end==false && circleOver==true)
      {
        start=!start;
      }  
      if(end==false && circleOver==false)
      {
        start=false;
        end=true;    
      }
      if(end==true)
      {
        background(0);
        strokeWeight(3);
        a=initradius;
        b=initradius;
        stroke(ye);
        ellipse(width/2,height/2,initradius,initradius);
        noFill();
        stroke(200);
        ellipse(width/2,height/2,endradius,endradius);
        end=false;
      }
    }
    
    void clickArea() 
    {
      if(overCircle()) 
      {
        circleOver = true;
      } 
      else 
      {
        circleOver = false;
      }
    }
    
    boolean overCircle() 
    {
      if(dist(width/2,height/2,mouseX,mouseY)< endradius/2)
      {
        return true;
      } 
      else 
      {
        return false;
      }
    }
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        strokeWeight(1);
        ellipse(pos.x, pos.y, 1, 1);
      }
     /*
      void resetEdges() {
        if (pos.x < -width/2) pos.x = -width/2;
        if (pos.x > width/2) pos.x = width/2;
        if (pos.y < -height/2) pos.y = -height/2;
        if (pos.y > height/2) pos.y = height/2;
      }
     */
      boolean isInsideBoundaries() {
        return (pos.x> 0 && pos.y> 0 && pos.x<width && pos.y<height);
      }
    }
    
  • Answer ✓

    Which line numbers do you want to change?

  • edited March 2017 Answer ✓

    this

    if (initNow==true) 
    

    is the same as

      if (initNow) 
    

    Similar

    • same situation here if (p.isInsideBoundaries()==true)

    • this if(end==false && circleOver==true) becomes if(!end && circleOver) where the ! means not / logical opposite

    allParticlesLeft

    I also made allParticlesLeft into a function that you have to call from draw(). It could also be called particleManager.

        boolean allParticlesLeft() {
    
          boolean buffer=true;
    
          for (Particle p : pars)
          {
            p.update();
            p.show();
            if (p.isInsideBoundaries())
            {
              buffer=false;
            }//if
          }//for 
          return buffer; 
          //
        } // function
    

    The states megastructure

    I noticed you use booleans to determine which situation you have in draw: start, end and initNow. Only one of them can be true, the 2 others are false. It fills your draw with if clauses and makes it hard to read.

    One is e.g. if (start==false && end==false) one is if (start) and if (initNow==true) but there are lines outside any of those ifs where it is unclear to which situation those lines belong (start == true? end == true).

    Instead make a variable state of type int which can be 0,1,2,3.... you can even give the states unique names like

    final int stateWaitAtBeginning =0; // numbers 0,1,2... must be unique
    final int stateStart=1; 
    final int stateEnd=2; 
    final int stateInitNow=3; 
    

    final means constant.

    Then use switch (state) { in draw. Nothing outside switch is allowed inside draw.

    This version won't work, but it shows the principal of using state:

    You can and should use the same switch(state) { megastructure you have in draw now also in mousePressed() and keyPressed().

    To correct this version search start and end and initNow and correct all the places. Those 3 variables we have to replace with state in different appropriate ways.

    You can also use functions in switch for each case...break section.

        final int initradius=50;
        final int endradius=250;
        final float theta0=0;  //Init angle
        final float thetaEnd=360;
    
        ArrayList<Particle> pars;
    
        int a=initradius;
        int b=initradius;
        int startTime;
        float x;
        float y;
        float z;
        float dtheta=400; //every ... degrees
        float vel;
        //boolean start=false;
        //boolean end=false;
        boolean circleOver = true;
        //boolean initNow=false;
        color g=color(0, 255, 0);
        color r=color(255, 0, 0);
        color ye=color(255, 255, 0);
    
    
        final int stateWaitAtBeginning =0; // numbers 0,1,2... must be unique
        final int stateStart=1; 
        final int stateEnd=2; 
        final int stateInitNow=3; 
    
        int state = stateWaitAtBeginning; 
    
        void setup()
        {
          size(320, 560);
          startTime=millis();
          background(0);
          fill(0);
          strokeWeight(3);
          stroke(ye);
          ellipse(width/2, height/2, initradius, initradius);
          noFill();
          stroke(200);
          ellipse(width/2, height/2, endradius, endradius);
    
          pars = new ArrayList<Particle>();
        }
    
        void draw() 
        {
    
          background(0);
    
          switch (state) {
    
          case stateWaitAtBeginning: 
            strokeWeight(3);
            stroke(ye);
            ellipse(width/2, height/2, initradius, initradius);
    
            // which state: ?????????
            noFill();
            stroke(200);
            ellipse(width/2, height/2, endradius, endradius);
            clickArea();
    
    
            break; // stateWaitAtBeginning
    
          case stateStart:
    
            z=random(0, 1);
            if ((millis() - startTime) >=200 )  //>=1000
            {
              startTime=millis();
              if (z>=0.5 && b<endradius)
              {
                if (a<b)
                {
                  fill(0);
                } else
                {
                  noFill();
                }
                a=a+20;
                stroke(g);
                ellipse(width/2, height/2, a, a);
              }
              if (z<0.5 && a<endradius)
              {
                if (b<a)
                {
                  fill(0);
                } else
                {
                  noFill();
                }
                b=b+20;
                stroke(r);
                ellipse(width/2, height/2, b, b);
              }
            }
            if (a==b)
            {
              stroke(ye);
              ellipse(width/2, height/2, a, a);
            }
    
            if (a>=endradius || b>=endradius)
            {
              state=stateInitNow;
              //initNow=true;
              //start=false;
              //end=true;
            }
    
            if (allParticlesLeft()==true) 
            {
              pars.clear();
            }
    
            break;  // end of stateStart
    
          case stateInitNow: 
            initSketch() ;
            // initNow=false;
            state=stateStart;
            break; //  stateInitNow 
    
          case stateEnd:
            // nothing
            break; 
    
          default:
            // Error ----
            println("Error 137"); 
            exit();
            break;
            //
          } // switch 
          //
        } // draw 
    
    
        boolean allParticlesLeft() {
    
          boolean buffer=true;
    
          for (Particle p : pars)
          {
            p.update();
            p.show();
            if (p.isInsideBoundaries())
            {
              buffer=false;
            }
          }//for 
          return buffer; 
          //
        } // function
    
        void initSketch()
        { 
          //Remove any mini-particle from the list... if any
          if (pars.size()!=0) {
            // pars.clear();
          }
    
          for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
            float unitx=cos(radians(a));
            float unity=sin(radians(a));
            float x=width/2+endradius/2*unitx;
            float y=height/2+endradius/2*unity;
    
            Particle p = new Particle(x, y);
            if (floor(a)%2==0) {
              vel=2;
            } else {
              vel=4;
            }
            p.vel=new PVector(vel*unitx, vel*unity);
            pars.add(p);
          }
        }
    
        void mousePressed()
        {
          if (state==stateWaitAtBeginning) {
            state=stateStart;
            return;
          } else if (state==stateStart && circleOver==true)
          {
            // start=!start;
            state=stateEnd;
          } else if (state==stateEnd && circleOver==false)
          {
            //start=false;
            //end=true;
          }
          if (state==stateEnd)
          {
            background(0);
            strokeWeight(3);
            a=initradius;
            b=initradius;
            stroke(ye);
            ellipse(width/2, height/2, initradius, initradius);
            noFill();
            stroke(200);
            ellipse(width/2, height/2, endradius, endradius);
            //end=false;
          }
        }
    
        void clickArea() 
        {
          if (overCircle()) 
          {
            circleOver = true;
          } else
          {
            circleOver = false;
          }
        }
    
        boolean overCircle() 
        {
          if (dist(width/2, height/2, mouseX, mouseY)< endradius/2)
          {
            return true;
          } else
          {
            return false;
          }
        }
        class Particle {
          PVector pos;
          PVector vel;
          PVector acc;
    
          Particle(float x, float y) {
            pos = new PVector(x, y);
            vel = new PVector(0, 0);
            acc = new PVector(0, 0);
          }
    
          void update() {
            vel.add(acc);
            pos.add(vel);
          }
    
          void applyForce(PVector force) {
            acc.add(force);
          }
    
          void show() {
            strokeWeight(1);
            ellipse(pos.x, pos.y, 1, 1);
          }
          /*
          void resetEdges() {
           if (pos.x < -width/2) pos.x = -width/2;
           if (pos.x > width/2) pos.x = width/2;
           if (pos.y < -height/2) pos.y = -height/2;
           if (pos.y > height/2) pos.y = height/2;
           }
           */
          boolean isInsideBoundaries() {
            return (pos.x> 0 && pos.y> 0 && pos.x<width && pos.y<height);
          }
        }
    
    1. When you draw ellipse a and b, draw them using a for loop instead of only drawing the final position.

    must be between line 56-87

    The purpose is that the ellipses don't disappear after drawing.

  • edited March 2017

    Can you explain the advantage of

    allParticlesLeft I also made allParticlesLeft into a function that you have to call from draw(). It could also be called particleManager.

    boolean allParticlesLeft() {
    
      boolean buffer=true;
    
      for (Particle p : pars)
      {
        p.update();
        p.show();
        if (p.isInsideBoundaries())
        {
          buffer=false;
        }//if
      }//for 
      return buffer; 
      //
    } // function
    
  • Answer ✓

    Can you explain the advantage of allParticlesLeft

    Yeah, once you identified a bunch of lines that belong together, it is great to make a function from it. Ideally draw() should be just commands calling other functions.

  • new version with functions in draw

    final int initradius=50;
    final int endradius=250;
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    
    ArrayList<Particle> pars;
    
    int a=initradius;
    int b=initradius;
    int startTime;
    float x;
    float y;
    float z;
    float dtheta=400; //every ... degrees
    float vel;
    //boolean start=false;
    //boolean end=false;
    boolean circleOver = true;
    //boolean initNow=false;
    color g=color(0, 255, 0);
    color r=color(255, 0, 0);
    color ye=color(255, 255, 0);
    
    
    final int stateWaitAtBeginning =0; // numbers 0,1,2... must be unique
    final int stateStart=1; 
    final int stateEnd=2; 
    final int stateInitNow=3; 
    
    int state = stateWaitAtBeginning; 
    
    // -----------------------------------------------------
    // Two CORE functions
    
    void setup()
    {
      size(320, 560);
      startTime=millis();
      background(0);
      fill(0);
      strokeWeight(3);
      stroke(ye);
      ellipse(width/2, height/2, initradius, initradius);
      noFill();
      stroke(200);
      ellipse(width/2, height/2, endradius, endradius);
    
      pars = new ArrayList<Particle>();
    }
    
    void draw() 
    {
    
      background(0);
    
      switch (state) {
    
      case stateWaitAtBeginning: 
        drawForStateWaitAtBeginning();
        break; // stateWaitAtBeginning
    
      case stateStart:
        drawForStateStart(); 
        break;  // end of stateStart
    
      case stateInitNow: 
        drawForStateInitNow();
        break; //  stateInitNow 
    
      case stateEnd:
        // nothing
        break; 
    
      default:
        // Error ----
        println("Error 137"); 
        exit();
        break;
        //
      } // switch 
      //
    } // draw 
    
    // -----------------------------------------------------
    // function called by draw directly
    
    void drawForStateWaitAtBeginning() {
      strokeWeight(3);
      stroke(ye);
      ellipse(width/2, height/2, initradius, initradius);
    
      // which state: ?????????
      noFill();
      stroke(200);
      ellipse(width/2, height/2, endradius, endradius);
      clickArea();
    }
    
    void drawForStateStart() {
    
      z=random(0, 1);
      if ((millis() - startTime) >=200 )  //>=1000
      {
        startTime=millis();
        if (z>=0.5 && b<endradius)
        {
          if (a<b)
          {
            fill(0);
          } else
          {
            noFill();
          }
          a=a+20;
          stroke(g);
          ellipse(width/2, height/2, a, a);
        }
        if (z<0.5 && a<endradius)
        {
          if (b<a)
          {
            fill(0);
          } else
          {
            noFill();
          }
          b=b+20;
          stroke(r);
          ellipse(width/2, height/2, b, b);
        }
      }//if
    
      if (a==b)
      {
        stroke(ye);
        ellipse(width/2, height/2, a, a);
      }
    
      if (a>=endradius || b>=endradius)
      {
        state=stateInitNow;
        //initNow=true;
        //start=false;
        //end=true;
      }
    
      if (allParticlesLeft()) 
      {
        pars.clear();
      }
    }
    
    void drawForStateInitNow() { 
      initSketch() ;
      // initNow=false;
      state=stateStart;
    }
    
    // -----------------------------------------------------
    // minor functions
    
    boolean allParticlesLeft() {
    
      boolean buffer=true;
    
      for (Particle p : pars)
      {
        p.update();
        p.show();
        if (p.isInsideBoundaries())
        {
          buffer=false;
        }
      }//for 
      return buffer; 
      //
    } // function
    
    void initSketch()
    { 
      //Remove any mini-particle from the list... if any
      if (pars.size()!=0) {
        // pars.clear();
      }
    
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        float x=width/2+endradius/2*unitx;
        float y=height/2+endradius/2*unity;
    
        Particle p = new Particle(x, y);
        if (floor(a)%2==0) {
          vel=2;
        } else {
          vel=4;
        }
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    
    void mousePressed()
    {
      if (state==stateWaitAtBeginning) {
        state=stateStart;
        return;
      } else if (state==stateStart && circleOver==true)
      {
        // start=!start;
        state=stateEnd;
      } else if (state==stateEnd && circleOver==false)
      {
        //start=false;
        //end=true;
      }
      if (state==stateEnd)
      {
        background(0);
        strokeWeight(3);
        a=initradius;
        b=initradius;
        stroke(ye);
        ellipse(width/2, height/2, initradius, initradius);
        noFill();
        stroke(200);
        ellipse(width/2, height/2, endradius, endradius);
        //end=false;
      }
    }
    
    void clickArea() 
    {
      if (overCircle()) 
      {
        circleOver = true;
      } else
      {
        circleOver = false;
      }
    }
    
    boolean overCircle() 
    {
      if (dist(width/2, height/2, mouseX, mouseY) < endradius/2)
      {
        return true;
      } else
      {
        return false;
      }
    }
    
    // =================================================================
    
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        strokeWeight(1);
        ellipse(pos.x, pos.y, 1, 1);
      }
      /*
      void resetEdges() {
       if (pos.x < -width/2) pos.x = -width/2;
       if (pos.x > width/2) pos.x = width/2;
       if (pos.y < -height/2) pos.y = -height/2;
       if (pos.y > height/2) pos.y = height/2;
       }
       */
      boolean isInsideBoundaries() {
        return (pos.x> 0 && pos.y> 0 && pos.x<width && pos.y<height);
      }
    }//class
    //
    
  • this way seems to make sense (different cases) but it also provides more questions than answeres :D if you start the code it's not doing what i want :D

  • Answer ✓

    I know

    you need to check mousePressed and other spots in ithe code

    as I said, look for start, end and initnow...

  • not sure what you meant by

    drawing ellipse with for-loops?

    do you want to use particle here?

    Here is an example without particles

    void setup() {
      size(555, 555);
      noFill();
    }
    
    void draw() {
      for (int i=3; i<10; i++) {
        ellipse(width/2, 255, i*22, i*22);
      }//for
    }
    
  • it was the idea of kfrajer. the command background(); in draw refreshes the display all the time, but i want that the ellipses are longer seen than a millisecond.

  • Answer ✓

    do you want to use particle here?

  • Answer ✓

    In my opinion it looks better already, because I moved the ellipse outside the inner ifs

    consider instead of adding 20 to a and to b just add 1 or 3

    final int initradius=50;
    final int endradius=250;
    final float theta0=0;  //Init angle
    final float thetaEnd=360;
    
    ArrayList<Particle> pars;
    
    int a=initradius;
    int b=initradius;
    int startTime;
    float x;
    float y;
    float z;
    float dtheta=400; //every ... degrees
    float vel;
    boolean start=false;
    boolean end=false;
    boolean circleOver = true;
    boolean initNow=false;
    color g=color(0, 255, 0);
    color r=color(255, 0, 0);
    color ye=color(255, 255, 0);
    
    void setup()
    {
      size(320, 560);
      startTime=millis();
      background(0);
      fill(0);
      strokeWeight(3);
      stroke(ye);
      ellipse(width/2, height/2, initradius, initradius);
      noFill();
      stroke(200);
      ellipse(width/2, height/2, endradius, endradius);
    
      pars = new ArrayList<Particle>();
    }
    
    void draw() 
    {
      background(0);
      if (start==false && end==false)
      {
        strokeWeight(3);
        stroke(ye);
        ellipse(width/2, height/2, initradius, initradius);
      }
      noFill();
      stroke(200);
      ellipse(width/2, height/2, endradius, endradius);
      clickArea();
      if (start)
      {
        z=random(0, 1);
        if ((millis() - startTime) >=200 )  //>=1000
        {
          startTime=millis();
          if (z>=0.5 && b<endradius)
          {
            if (a<b)
            {
              fill(0);
            } else
            {
              noFill();
            }
            a=a+20;
          }
          if (z<0.5 && a<endradius)
          {
            if (b<a)
            {
              fill(0);
            } else
            {
              noFill();
            }
            b=b+20;
          }
        }
        if (a==b)
        {
          // set color of A ellipse (named a) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
          //stroke(ye);
          //ellipse(width/2, height/2, a, a);
        }
    
        if (a>=endradius || b>=endradius)
        {
          initNow=true;
          start=false;
          end=true;
        }
    
        stroke(g); // use color of A ellipse (named a) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        ellipse(width/2, height/2, a, a);
    
        stroke(r);
        ellipse(width/2, height/2, b, b);
      }//start 
    
    
    
      if (initNow==true) 
      {
        initSketch() ;
        initNow=false;
        return;
      } else
      {
        initNow=false;
      }  
    
      boolean allParticlessLeft=true; 
      for (Particle p : pars)
      {
        p.update();
        p.show();
        if (p.isInsideBoundaries()==true)
        {
          allParticlessLeft=false;
        }
      } 
      if (allParticlessLeft==true) 
      {
        pars.clear();
      }
      strokeWeight(3);
    }
    
    void initSketch()
    { 
      //Remove any mini-particle from the list... if any
      if (pars.size()!=0) {
        // pars.clear();
      }
    
      for (float a=theta0; a<thetaEnd; a+=thetaEnd/dtheta) {
    
        float unitx=cos(radians(a));
        float unity=sin(radians(a));
        float x=width/2+endradius/2*unitx;
        float y=height/2+endradius/2*unity;
    
        Particle p = new Particle(x, y);
        if (floor(a)%2==0) {
          vel=2;
        } else {
          vel=4;
        }
        p.vel=new PVector(vel*unitx, vel*unity);
        pars.add(p);
      }
    }
    
    void mousePressed()
    {
      if (end==false && circleOver==true)
      {
        start=!start;
      }  
      if (end==false && circleOver==false)
      {
        start=false;
        end=true;
      }
      if (end==true)
      {
        background(0);
        strokeWeight(3);
        a=initradius;
        b=initradius;
        stroke(ye);
        ellipse(width/2, height/2, initradius, initradius);
        noFill();
        stroke(200);
        ellipse(width/2, height/2, endradius, endradius);
        end=false;
      }
    }
    
    void clickArea() 
    {
      if (overCircle()) 
      {
        circleOver = true;
      } else
      {
        circleOver = false;
      }
    }
    
    boolean overCircle() 
    {
      if (dist(width/2, height/2, mouseX, mouseY)< endradius/2)
      {
        return true;
      } else
      {
        return false;
      }
    }
    class Particle {
      PVector pos;
      PVector vel;
      PVector acc;
    
      Particle(float x, float y) {
        pos = new PVector(x, y);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        vel.add(acc);
        pos.add(vel);
      }
    
      void applyForce(PVector force) {
        acc.add(force);
      }
    
      void show() {
        strokeWeight(1);
        ellipse(pos.x, pos.y, 1, 1);
      }
      /*
      void resetEdges() {
       if (pos.x < -width/2) pos.x = -width/2;
       if (pos.x > width/2) pos.x = width/2;
       if (pos.y < -height/2) pos.y = -height/2;
       if (pos.y > height/2) pos.y = height/2;
       }
       */
      boolean isInsideBoundaries() {
        return (pos.x> 0 && pos.y> 0 && pos.x<width && pos.y<height);
      }
    }
    
  • edited March 2017

    Yes this is what it should look like. Can't believe that I did not try this. I will now try to use the different cases like you considered and then it is finished. Thanks a lot!

  • Can you please explain me how to read line 136, there is no appropriate example in the reference.

  • Answer ✓

    !=

    means not equal

    size is the length of an ArrayList

Sign In or Register to comment.