Adding Particle Background

edited May 2015 in How To...

I am really new at processing but I am working on a code with a current particle system and want to add another system of particles as a background. How do I go about adding a second particle to an existing code without it effecting the current particle.

Any help at all would be greatly appreciated. I am trying to teach myself coding and just need to know the right direction to look.

Thanks,

Tagged:

Answers

  • If you wrote your ParticleSystem as a class, you'd just add a new instance of that class (probably with different parameters).

    It's hard to help you without seeing the state of your code.

  • Answer ✓
    class Particle {
      float px, py;
      color c;
      Particle(float ipx, float ipy, color ic) { 
        px=ipx;
        py=ipy; 
        c=ic;
      }
      void draw() { 
        fill(c); 
        noStroke(); 
        rect(px-1, py-1, 2, 2);
      }
      void move() { 
        px+=random(-1, 1); 
        py+=random(-1, 1);
      }
    }
    
    class PS {
      Particle[] ps;
      PS(int is, float ix, float iy, float iw, float ih, color ic){
        ps = new Particle[is];
        for(int i=0;i<ps.length;i++){
          ps[i] = new Particle(ix + random(iw),iy + random(ih),ic);
        }
      }
      void draw(){
        for(int i=0;i<ps.length;i++){
          ps[i].move();
          ps[i].draw();
        }
      }
    }
    
    PS sys1;
    PS sys2;
    
    void setup() {
      size(400, 400);
      sys1 = new PS(100,20,20,40,40,color(255,0,128));
      sys2 = new PS(1000,100,100,100,100,color(0,255,0));
    }
    
    void draw() {
      background(0);
      sys1.draw();
      sys2.draw();
    }
    
  • edited May 2015

    double comment

  • edited May 2015

    I'm using samples to patch together and try to teach myself from that as I said I am very new. Thanks for the reply here is the code.

    Main Sketch Page.

    import SimpleOpenNI.*;
    import msafluid.*;
    import javax.media.opengl.GL2;
    
    SimpleOpenNI context;
    boolean autoCalib=true;
    final float FLUID_WIDTH = 120;
    
    float invWidth, invHeight;    // inverse of screen dimensions
    float aspectRatio, aspectRatio2;
    
    MSAFluidSolver2D fluidSolver;
    PImage imgFluid;
    
    ParticleSystem particleSystem;
    
    float bodyAlpha = 0; // originally 100
    
    float velScale = 0.0001;
    
    float kinectWidth, kinectHeight;
    float scaleWidth, scaleHeight;
    
    void setup() {
      //size(context.depthWidth(), context.depthHeight());
      size(displayWidth, displayHeight, P3D);    // use OPENGL rendering for bilinear filtering on texture
    //    size(screen.width * 49/50, screen.height * 49/50, OPENGL);
       // hint( ENABLE_OPENGL_4X_SMOOTH );    // Turn on 4X antialiasing
    
        invWidth = 1.0f/width;
        invHeight = 1.0f/height;
        aspectRatio = width * invHeight;
        aspectRatio2 = aspectRatio * aspectRatio;
    
      context = new SimpleOpenNI(this);
    
      // enable depthMap generation 
      context.enableDepth();
      context.setMirror(true);  // mirrors the image
      kinectWidth = context.depthWidth();
      kinectHeight = context.depthHeight();
      scaleWidth = width/kinectWidth;
      scaleHeight = height/kinectHeight;
    
    
      // enable skeleton generation for all joints
      context.enableUser();
    
      // create fluid and set options
      fluidSolver = new MSAFluidSolver2D((int)(FLUID_WIDTH), (int)(FLUID_WIDTH * height/width));
        fluidSolver.enableRGB(true).setFadeSpeed(0.003).setDeltaT(0.5).setVisc(0.0001);
    
      // create image to hold fluid picture
      imgFluid = createImage(fluidSolver.getWidth(), fluidSolver.getHeight(), RGB);
    
      // create particle system
        particleSystem = new ParticleSystem();
    }
    
    void draw() {
      // update the cam
      context.update();
    
      // update the fluid simulation
      fluidSolver.update();
    
      // draw depthImageMap
      //image(context.depthImage(),0,0);
    
       // draw the fluid
       for(int i=0; i<fluidSolver.getNumCells(); i++) {
           int d = 2;
           imgFluid.pixels[i] = color(fluidSolver.r[i] * d, fluidSolver.g[i] * d, fluidSolver.b[i] * d);
       }  
       imgFluid.updatePixels();//  fastblur(imgFluid, 2);
       image(imgFluid, 0, 0, width, height);
    
      // draw the skeleton if it's available
      int[] userList = context.getUsers();
      for(int i=0;i<userList.length;i++)
      {
        if(context.isTrackingSkeleton(userList[i]))
          drawSkeleton(userList[i]);
      }   
    
      particleSystem.updateAndDraw();
    
    }
    
    // remember the last 2D point
    PVector lastScreenPosLeftHand = new PVector(); 
    PVector lastScreenPosRightHand = new PVector(); 
    PVector lastScreenPosHead = new PVector();
    PVector lastScreenPosNeck = new PVector();
    PVector lastScreenPosLeftShoulder = new PVector();
    PVector lastScreenPosRightShoulder = new PVector();
    PVector lastScreenPosLeftElbow = new PVector();
    PVector lastScreenPosRightElbow = new PVector();
    PVector lastScreenPosTorso = new PVector();
    PVector lastScreenPosLeftHip = new PVector();
    PVector lastScreenPosRightHip = new PVector();
    PVector lastScreenPosLeftKnee = new PVector();
    PVector lastScreenPosRightKnee = new PVector();
    PVector lastScreenPosLeftFoot = new PVector();
    PVector lastScreenPosRightFoot = new PVector();
    
    // ARRAYS
    
    PVector[] lastScreenPos = new PVector[15];
    
    int[] jointColor = {
      216,
      216,
      216,
      216,
      216,
      216,
      216,
      216,
      216,
      216,
      216,
      216,
      216,
      216,
      216,
    };
    
    // draw the skeleton with the selected joints
    void drawSkeleton(int userId) {
    
      // to get the 3d joint data
      // from https://github.com/acm-uiuc/FallingBlocks/blob/master/PhsyicsKinect/PhsyicsKinect.pde
    
      // this array goes inside for some reason....
      int[] jointID = {
        SimpleOpenNI.SKEL_LEFT_HAND, 
        SimpleOpenNI.SKEL_RIGHT_HAND,
        SimpleOpenNI.SKEL_HEAD,
        SimpleOpenNI.SKEL_NECK,
        SimpleOpenNI.SKEL_LEFT_SHOULDER,
        SimpleOpenNI.SKEL_RIGHT_SHOULDER,
        SimpleOpenNI.SKEL_LEFT_ELBOW,
        SimpleOpenNI.SKEL_RIGHT_ELBOW,
        SimpleOpenNI.SKEL_TORSO,
        SimpleOpenNI.SKEL_LEFT_HIP,
        SimpleOpenNI.SKEL_RIGHT_HIP,
        SimpleOpenNI.SKEL_LEFT_KNEE,
        SimpleOpenNI.SKEL_RIGHT_KNEE,
        SimpleOpenNI.SKEL_LEFT_FOOT,
        SimpleOpenNI.SKEL_RIGHT_FOOT,
      };
    
      for (int i=0; i<jointID.length; i++) {
    
        PVector jointPos = new PVector();  // 3D point
        PVector screenPos = new PVector();  // 2D point
        context.getJointPositionSkeleton(userId, jointID[i], jointPos);
        context.convertRealWorldToProjective(jointPos, screenPos);
        //println(jointPos);
        fill(255, 255, 255, bodyAlpha);
        noStroke();
        ellipse(screenPos.x*scaleWidth, screenPos.y*scaleHeight, jointPos.z/100.0, jointPos.z/100.0);
    
        if (lastScreenPos[i] == null) {    // if there's nothing in there   
          lastScreenPos[i] = screenPos;    // use the initial position
        }
    
        addForce(screenPos.x, screenPos.y, screenPos.x-lastScreenPos[i].x, screenPos.y-lastScreenPos[i].y, jointColor[i]);
        lastScreenPos[i] = screenPos; // saving current value for next time (to remember the last point)
      }
    
    }
    
    // add force and dye to fluid, and create particles
    // x & y are position
    // d = derivative of the position
    // dx & dy = velocity
    void addForce(float x, float y, float dx, float dy, float hue) {
      addForceAbs(x/(kinectWidth), y/(kinectHeight), dx/(kinectWidth), dy/(kinectHeight), hue);
    }
    
    void addForceAbs(float x, float y, float dx, float dy, float hue) {
        float speed = dx * dx  + dy * dy * (kinectHeight)/(kinectWidth);    // balance the x and y components of speed with the screen aspect ratio
    
        if(speed > 0) {
            if(x<0) x = 0; 
            else if(x>1) x = 1;
            if(y<0) y = 0; 
            else if(y>1) y = 1;
    
            float colorMult = 5;
            float velocityMult = 30.0f;
    
            int index = fluidSolver.getIndexForNormalizedPosition(x, y);
    
            color drawColor;
    
            colorMode(HSB, 360, 1, 1);
            hue = hue = ((x + y) * 180 + frameCount) % 360;
            //float hue = ((x + y) * 180 + frameCount) % 360;
            drawColor = color(hue, 1, 1);
            colorMode(RGB, 1);  
    
            fluidSolver.rOld[index]  += red(drawColor) * colorMult;
            fluidSolver.gOld[index]  += green(drawColor) * colorMult;
            fluidSolver.bOld[index]  += blue(drawColor) * colorMult;
    
            particleSystem.addParticles(x * width, y * height, 10);
            fluidSolver.uOld[index] += dx * velocityMult;
            fluidSolver.vOld[index] += dy * velocityMult;
        }
    }
    
    void onNewUser(SimpleOpenNI curContext, int userId)
    {
        println("onNewUser - userId: " + userId);
        println("\tstart tracking skeleton");
    
        context.startTrackingSkeleton(userId);
    }
    
    void onLostUser(SimpleOpenNI curContext, int userId)
    {
        println("onLostUser - userId: " + userId);
    }
    
    void onVisibleUser(SimpleOpenNI curContext, int userId)
    {
        //println("onVisibleUser - userId: " + userId);
    }
    
  • edited May 2015
    class Particle {
        final static float MOMENTUM = 0.5;
        final static float FLUID_FORCE = 0.6;
    
        float x, y;
        float vx, vy;
        float radius;       // particle's size
        float alpha;
        float mass;
    
        void init(float x, float y) {
            this.x = x;
            this.y = y;
            vx = 0;
            vy = 0;
            radius = 5;
            alpha  = random(0.3, 1);
            mass = random(0.1, 1);
        }
    
        void update() {
            // only update if particle is visible
            if(alpha == 0) return;
    
            // read fluid info and add to velocity
            int fluidIndex = fluidSolver.getIndexForNormalizedPosition(x * invWidth, y * invHeight);
            vx = fluidSolver.u[fluidIndex] * width * mass * FLUID_FORCE + vx * MOMENTUM;
            vy = fluidSolver.v[fluidIndex] * height * mass * FLUID_FORCE + vy * MOMENTUM;
    
            // update position
            x += vx;
            y += vy;
    
            // bounce of edges
            if(x<0) {
                x = 0;
                vx *= -1;
            }
            else if(x > width) {
                x = width;
                vx *= -1;
            }
    
            if(y<0) {
                y = 0;
                vy *= -1;
            }
            else if(y > height) {
                y = height;
                vy *= -1;
            }
    
            // hackish way to make particles glitter when the slow down a lot
            if(vx * vx + vy * vy < 1) {
                vx = random(-1, 1);
                vy = random(-1, 1);
            }
    
            // fade out a bit (and kill if alpha == 0);
            alpha *= 0.999;
            if(alpha < 0.01) alpha = 0;
    
        }
    
        void updateVertexArrays(int i, FloatBuffer posBuffer, FloatBuffer colBuffer) {
            int vi = i * 4;
            posBuffer.put(vi++, x - vx);
            posBuffer.put(vi++, y - vy);
            posBuffer.put(vi++, x);
            posBuffer.put(vi++, y);
    
            int ci = i * 6;
            colBuffer.put(ci++, alpha);
            colBuffer.put(ci++, alpha);
            colBuffer.put(ci++, alpha);
            colBuffer.put(ci++, alpha);
            colBuffer.put(ci++, alpha);
            colBuffer.put(ci++, alpha);
        }
    
        void drawOldSchool(GL2 gl) {
            gl.glColor3f(alpha, alpha, alpha);
            gl.glVertex2f(x-vx, y-vy);
            gl.glVertex2f(x, y);
        }
    }
    
  • edited May 2015
    import java.nio.FloatBuffer;
    import com.sun.opengl.util.*;
    
    boolean renderUsingVA = true;
    
    void fadeToColor(GL2 gl, float r, float g, float b, float speed) {
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);
        gl.glColor4f(r, g, b, speed);
        gl.glBegin(gl.GL_QUADS);
        gl.glVertex2f(0, 0);
        gl.glVertex2f(width, 0);
        gl.glVertex2f(width, height);
        gl.glVertex2f(0, height);
        gl.glEnd();
    }
    
    class ParticleSystem {
        FloatBuffer posArray;
        FloatBuffer colArray;
    
        final static int maxParticles = 5000;
        int curIndex;
    
        Particle[] particles;
    
        ParticleSystem() {
            particles = new Particle[maxParticles];
            for(int i=0; i<maxParticles; i++) particles[i] = new Particle();
            curIndex = 0;
    
            posArray = BufferUtil.newFloatBuffer(maxParticles * 2 * 2);// 2 coordinates per point, 2 points per particle (current and previous)
            colArray = BufferUtil.newFloatBuffer(maxParticles * 3 * 2);
        }
    
        void updateAndDraw(){
            //OPENGL Processing 2.1
            PGL pgl;                                  // JOGL's GL object
            pgl = beginPGL();
            GL2 gl = ((PJOGL)pgl).gl.getGL2();       // processings opengl graphics object               
    
            gl.glEnable( GL2.GL_BLEND );             // enable blending
    
            gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE);  // additive blending (ignore alpha)
            gl.glEnable(GL2.GL_LINE_SMOOTH);        // make points round
            gl.glLineWidth(1);
    
    
            if(renderUsingVA) {
                for(int i=0; i<maxParticles; i++) {
                    if(particles[i].alpha > 0) {
                        particles[i].update();
                        particles[i].updateVertexArrays(i, posArray, colArray);
                    }
                }    
                gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
                gl.glVertexPointer(2, GL2.GL_FLOAT, 0, posArray);
    
                gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
                gl.glColorPointer(3, GL2.GL_FLOAT, 0, colArray);
    
                gl.glDrawArrays(GL2.GL_LINES, 0, maxParticles * 2);
            } 
            else {
                gl.glBegin(gl.GL_LINES);               // start drawing points
                for(int i=0; i<maxParticles; i++) {
                    if(particles[i].alpha > 0) {
                        particles[i].update();
                        particles[i].drawOldSchool(gl);    // use oldschool renderng
                    }
                }
                gl.glEnd();
            }
    
            gl.glDisable(GL2.GL_BLEND);
            endPGL();
        }
    
        void addParticles(float x, float y, int count ){
            for(int i=0; i<count; i++) addParticle(x + random(-15, 15), y + random(-15, 15));
        }
    
        void addParticle(float x, float y) {
            particles[curIndex].init(x, y);
            curIndex++;
            if(curIndex >= maxParticles) curIndex = 0;
        }
    }
    
  • Cleary I need to go back to the basics as your answer didn't really help me much.. I am just going to need to read up more and learn what it all means. I have three pages my main sketch, a particle, and a particle system. I don't even know how to go about adding the second particle or where(page) for that matter. I really appreciate your help.

  • Perhaps read (again?) How to format code and text for proper formatting of your code. Then edit your messages to make them readable.
    Remove the useless backticks (only to be used for small code fragments), select your code and hit the C button (or Ctrl+O).

  • i have formatted code. the first bit was too large to post as a single block but contained hundreds of lines that were commented out so i have deleted them.

    you stand more chance of getting answers if your examples are concise and don't require the use of specialized libraries. and if your code is formatted correctly.

    and please don't start duplicate (or triplicate) questions

    (philho, the C button inserts the useless backticks if pressed at the wrong time or when the wrong thing is selected. it's annoying.)

  • edited May 2015 Answer ✓

    well, it's basically about making two sketches into one.

    the current sketch is number 1, the background particles are sketch #2.

    you can start making #2 as a separate sketch

    once #2 works, join #1 and #2

    to do so in the new sketch #3

    • have all the classes from #1 & #2 (they must have different names)

    • join the two setups so you have only one setup and one command size()

    • join the two draws

    have the functions copied as well

    ;-)

  • Hello, I'm really sorry to bother you. I'm new here and this is my first approach to Processing. For an exam I have to make a prototype for an app and I would like to simulate it using processing. I was wondering if it's possible to divide the screen in two parts having different interactions. The interactive effects I'm trying to customize is this: http://processingjs.org/learning/basic/distance2d/ Do you know have to have two of them one under the other? Could anyone help me solving this? Thank you so much for everyone in advance Best

  • it is possible.

    you can define two rects for upper and lower part

    when you do something like drawing the circles just draw them only above the middle line....

Sign In or Register to comment.