How to make it fast ?

edited November 2013 in Questions about Code

Below, I have shown a Splash code. It generates a random splash on screen and whenever you click it drips down to screen. I have to this over a video feed so I have used PGraphics Layer without any background so that it can show the dripping effect but using PGraphics made it extremely slow so I used P3D render, thought it would make it run fast but it also not working and using P3D render loosed its transparency.

So I have two questions:

  1. Is it possible to create Transparent PGraphics Layer with P3D render because I have found it is impossible (As I thought) . Whenever I try putting P3D render in testLayer = creategraphics(w,h,P3D); it shows a grey screen.
  2. How to make it fast ? Because without any PGraphics and setting canvas background(-1) it run fast.

      ArrayList splatpoop;
      PGraphics testLayer;
      void setup()
      {
        size(400, 400, P3D);
        splatpoop = new ArrayList();
        testLayer = createGraphics(width, height, P3D);
      }
    
      void draw() {
        println(frameRate);
        background(-1);
        for (int i=0; i<splatpoop.size(); i++) {
          Splash s = (Splash) splatpoop.get(i);
          s.display();
          s.update();
        }
        testLayer.clear();
        image(testLayer,0,0);
      }
    
      void mousePressed() {
        color splc = (color) random(#000000);
        for (float i=3; i<29; i+=.35) {
          Splash sp = new Splash(mouseX, mouseY, i, splc);
          splatpoop.add(sp);
        }
      }
    
    
      class Splash {
        int x, y;
        float rad, angle, i;
        color c;
        Splash(int _x, int _y, float _i, color splc) {
          x = _x;
          y = _y;
          i = _i;
          rad = random(2, 50);
          angle = random(0, TWO_PI);
          c = splc;
        }
    
        void display() {
          testLayer.beginDraw();
          testLayer.fill(c);
          testLayer.noStroke();
          float spotX = x + cos(angle)*2*i;
          float spotY = y + sin(angle)*3*i;
          testLayer.ellipse(spotX, spotY, rad-i, rad-i+1.8);
          testLayer.endDraw();
        }
        void update() {
          y = y+1;
        }
      }
    

Extended question why this is not working ? It should capture the ellipse inside the polygon and leave the rest of them to slide down to the screen.

       ArrayList splatpoop;
      import java.util.*;
      Poly p;
      void setup() {
        size(500, 500);
        splatpoop = new ArrayList();
        //--------------------------
        int[] x = { 
          (int)random(20), (int)random(120), (int)random(320), (int)random(420), (int)random(250), (int)random(500)
          };
        int[] y = { 
          (int)random(500), (int)random(120), (int)random(320), (int)random(420), (int)random(250), (int)random(500)
          };
          p = new Poly(x, y, 6);
        background(-1);
        noStroke();
        //--------------------------
      }

      void draw() {
       background(-1);
        //--------------Splash holding inside the polygon------------------------
        fill(#FFE603);
        p.drawMe();
          for (int i=0; i<splatpoop.size(); i++) {
          Splash sp = (Splash) splatpoop.get(i);
          sp.display();
          sp.update();
          if (p.contains(sp.x, sp.y)) {
            sp.display();
          } 
          else {
            sp.update();
            if (sp.y>height) {
              splatpoop.remove(i);
            }
          }
        }
      }
      //-----------------------

      void mousePressed() {
        color splc = (color) random(#000000);
        for (float i=3; i<29; i+=.35) {
          Splash sp = new Splash(mouseX, mouseY, i, splc);
          splatpoop.add(sp);
        }
      }
      //-----------------------

      class Splash {
        int x, y;
        float rad, angle, i;
        color c;
        Splash(int _x, int _y, float _i, color splc) {
          x = _x;
          y = _y;
          i = _i;
          rad = random(2, 50);
          angle = random(0, TWO_PI);
          c = splc;
        }

        void display() {

          fill(c);
          noStroke();
          float spotX = x + cos(angle)*2*i;
          float spotY = y + sin(angle)*3*i;
          ellipse(spotX, spotY, rad-i, rad-i+1.8);

        }
        void update() {
          y = y+1;
        }
      }

      //---------------------------------------------
      class Poly extends java.awt.Polygon {
        public Poly(int[] x, int[] y, int n) {
          //call the java.awt.Polygon constructor
          super(x, y, n);
        }

        void drawMe() {
          beginShape();
          for (int i = 0; i < npoints; i++) {
            vertex(xpoints[i], ypoints[i]);
          }
          endShape(CLOSE);
        }
      }

Answers

  • Not sure on what else to do to make it faster but one thing is that after the splats go out of the screen remove them from the arraylist.

  • edited November 2013

    Actually I have already solved it and I am already removing the elements from the splatpoop ArrayList you can see it in line 35.

    What I did to make it fast is that I have put beginDraw and endDraw PGraphics functions in the draw method because when you draw calling these methods in class, make it slow.

    So this not the problem anymore but can you suggest me anything in the second part of the question where this is interacting with the polygon?

    Here is the code :

        ArrayList splatpoop;
        PGraphics testLayer;
        void setup()
        {
          size(400, 400);
          splatpoop = new ArrayList();
          testLayer = createGraphics(width, height);
        }
    
        void draw() {
          //println(frameRate);
          background(-1);
          testLayer.beginDraw(); ////////////////////////////
          for (int i=0; i<splatpoop.size(); i++) {
            Splash s = (Splash) splatpoop.get(i);
            s.display();
            if(random(80)<40)
            s.update();
            if (s.y>height)
              splatpoop.remove(i);
          }
          testLayer.endDraw();///////////////////////////////
          image(testLayer,0,0);
        }
    
        void mousePressed() {
          color splc = (color) random(#000000);
          for (float i=3; i<29; i+=.35) {
            Splash sp = new Splash(mouseX, mouseY, i, splc);
            splatpoop.add(sp);
          }
        }
    
    
        class Splash {
          int x, y;
          float rad, ellipseangle, i;
          color c;
          Splash(int _x, int _y, float _i, color splc) {
            x = _x;
            y = _y;
            i = _i;
            rad = random(2, 50);
            ellipseangle = random(0, TWO_PI);
            c = splc;
          }
    
          void display() {
    
            testLayer.fill(c);
            testLayer.noStroke();
            float spotX = x + cos(ellipseangle)*2*i;
            float spotY = y + sin(ellipseangle)*3*i;
            testLayer.ellipse(spotX, spotY, rad-i, rad-i+random(1, 2));
          }
          void update() {
            y = y+1;
          }
        }
    
  • edited November 2013 Answer ✓

    You can even try to move beginDraw() into setup() after createGraphics()! $-)
    I've never seen the need to keep issuing beginDraw() more than once for each PGraphics! :-bd

    Also, to eliminate the need of casting (Splash) for get(), declare splatPoop w/ ArrayList<Splash>! =:)

  • Oh Thanks GoToLoop .... Nice hack =D> =D> . Actually I haven't seen this hack mention anywhere on processing website. :) =D>

  • edited November 2013

    @GoToLoop can you help me in the second part of the Question.

    Second Part was: When you click on the canvas it generates the splash. The Splash particle those are out side the polygon slides down to the bottom of the screen and those are inside the polygon get stuck inside the polygon.

    The problem is when splash slides down and hits the polygon the all the Splash particle gets stopped together whether they are outside of the polygon or inside of the polygon.

    Code for the second question

          ArrayList splatpoop;
          import java.util.*;
          Poly p;
          void setup() {
            size(500, 500);
            splatpoop = new ArrayList();
            //--------------------------
            int[] x = { 
              (int)random(20), (int)random(120), (int)random(320), (int)random(420), (int)random(250), (int)random(500)
              };
            int[] y = { 
              (int)random(500), (int)random(120), (int)random(320), (int)random(420), (int)random(250), (int)random(500)
              };
              p = new Poly(x, y, 6);
            background(-1);
            noStroke();
            //--------------------------
          }
    
          void draw() {
           //background(-1);
            //--------------Splash holding inside the polygon------------------------
            fill(#FFE603);
            p.drawMe();
              for (int i=0; i<splatpoop.size(); i++) {
              Splash sp = (Splash) splatpoop.get(i);
              sp.display();
              if (p.contains(sp.x, sp.y)) {
                sp.display();
              } 
              else {
                sp.update();
                if (sp.y>height) {
                  splatpoop.remove(i);
                }
              }
            }
          }
          //-----------------------
    
          void mousePressed() {
            color splc = (color) random(#000000);
            for (float i=3; i<29; i+=.35) {
              Splash sp = new Splash(mouseX, mouseY, i, splc);
              splatpoop.add(sp);
            }
          }
          //-----------------------
    
          class Splash {
            int x, y;
            float rad, angle, i;
            color c;
            Splash(int _x, int _y, float _i, color splc) {
              x = _x;
              y = _y;
              i = _i;
              rad = random(2, 50);
              angle = random(0, TWO_PI);
              c = splc;
            }
    
            void display() {
    
              fill(c);
              noStroke();
              float spotX = x + cos(angle)*2*i;
              float spotY = y + sin(angle)*3*i;
              ellipse(spotX, spotY, rad-i, rad-i+1.8);
    
            }
            void update() {
              y = y+1;
            }
          }
    
          //---------------------------------------------
          class Poly extends java.awt.Polygon {
            public Poly(int[] x, int[] y, int n) {
              //call the java.awt.Polygon constructor
              super(x, y, n);
            }
    
            void drawMe() {
              beginShape();
              for (int i = 0; i < npoints; i++) {
                vertex(xpoints[i], ypoints[i]);
              }
              endShape(CLOSE);
            }
          }
    
Sign In or Register to comment.