... be able to draw smoke to canvas

edited October 2015 in Questions about Code

Dear Community,

I am quite new to processing and this maybe a simple question. I downloaded a sketch from OpenProcessing which is generating smoke which is working perfectly. I added a simple clipping mask and now I would like to paint the canvas below with the generated smoke. Basically the smoke should follow the mouse pointer as now but the generated points should also paint the canvas instead of just vaporizing. I can't figure out how to make that happen in my script, it would be great if anyone could point me in the right direction.

Here is the code I am currently using:

PVector rootn = new PVector(random(123), random(123));//noise root
PVector speedn = new PVector(random(-.01, .01), random(-.01, .01));//noise speed
ArrayList<Part> parts = new ArrayList<Part>(), saveparts = new ArrayList<Part>(), toAdd = new ArrayList<Part>();//Parts
PVector m, pm, pos;//mouse, previous mouse
float maxD = 10;//max distance between two smokes
PGraphics pg, pg2;
int b = 10;
PImage img;
PImage imgMask;


void setup()
{
  smooth(8);
  size(600, 800, P2D);
  pg = createGraphics(width, height, P2D);

  img = loadImage("mask.png");

}

void draw()
{

  pg.beginDraw();

  pg.noStroke();

  pg.rect(0, 0, width, height);

  for (Part p : toAdd)
  {
    parts.add(p);
  }
  toAdd = new ArrayList<Part>();



  rootn.add(speedn);


  m = new PVector(mouseX, mouseY);

  int nb = parts.size()-1;
  if (mousePressed && nb < 8000)  
  {
    if (pm == null) pm = m.get();
    else
    {
      float d = PVector.dist(pm, m);
      if ((pm.x != m.x || pm.y != m.y) && d > maxD)
      {
        int n = int(d / maxD);
        PVector tmp = PVector.sub(m, pm);
        tmp.normalize();
        tmp.mult(maxD);
        PVector tmp2 = m.get();
        for (int i = 0; i < n; i++)
        {
          tmp2.sub(tmp);
          parts.add(new Part(tmp2, (int)random(0, 25), (int)random(50, 140), 0)); 
        }
      }
    }
    parts.add(new Part(m, (int)random(0, 25), (int)random(50, 140), 0));
    pm = m.get();
  }
  nb = parts.size()-1;
  for (int i = nb; i > -1; i--)
  {
    if (parts.get(i).display())
    {
     parts.remove(i);
    }
  }


  pg.endDraw();
  image(pg, 0, 0);



  //Clipping Mask
  image(img, 0, 0);

}

void mouseReleased()
{

  pm = null;
}

class Part
{
  float rad, c = random(.6, .8), theta = random(TWO_PI), nx, ny;
  int life, age, mod = (int)random(30, 40);
  PVector pos;

  Part(PVector p, int a, int l, float r)
  {
    pos = p.get();
    age = a;
    life = l;
    rad = r;
  }

  Boolean display()
  {

    nx = noise(rootn.x + pos.x/500)-.5;
    ny = noise(rootn.y + pos.y/500)-.5;


    pos.add(new PVector(6*nx, 6*ny));


    rad += cos(map(age, 0, life, 0, HALF_PI)) * c;

    pg.stroke(map(age, 0, life, 1, 255),map(age, 100, life, 1, 255),map(age, 200, life, 1, 255), 200 * sq(map(age, 0, life, 1, 0)));
    pg.strokeWeight(rad);

    pg.point(pos.x, pos.y);

    if (age++ % mod == 0)//split the Part in two
    {
      toAdd.add(new Part(new PVector(pos.x + rad/3 * cos(theta), pos.y + rad/3 * sin(theta)), age, life, rad * random(.6, .8))); // size of smoke set here
      toAdd.add(new Part(new PVector(pos.x - rad/3 * cos(theta), pos.y - rad/3 * sin(theta)), age, life, rad * random(.6, .8)));//.6
      age = life+1;
    }
    return age > life;
  }
}

Answers

  • We can't run this code as we don't have mask.png

  • edited October 2015

    Hello _vk,

    here the code without the mask, as it is not necessary to display the smoke. I also adapted the code little so it does not throw any out of bound error:

           PVector rootn = new PVector(random(123), random(123));//noise root
              PVector speedn = new PVector(random(-.01, .01), random(-.01, .01));//noise speed
              ArrayList<Part> parts = new ArrayList<Part>(), saveparts = new ArrayList<Part>(), toAdd = new ArrayList<Part>();//Parts
              PVector m, pm, pos;//mouse, previous mouse
              float maxD = 10;//max distance between two smokes
              PGraphics pg, pg2;
              int b = 10;
              PImage img;
              PImage imgMask;
    
    
              void setup()
              {
                smooth(8);
                size(600, 800, P2D);
                pg = createGraphics(width, height, P2D);
    
               // img = loadImage("mask.png");
    
              }
    
              void draw()
              {
    
                pg.beginDraw();
    
                pg.noStroke();
    
                pg.rect(0, 0, width, height);
    
                for (Part p : toAdd)
                {
                  parts.add(p);
                }
                toAdd = new ArrayList<Part>();
    
    
    
                rootn.add(speedn);
    
    
                m = new PVector(mouseX, mouseY);
    
                int nb = parts.size()-1;
                if (mousePressed && nb < 8000)  
                {
                  if (pm == null) pm = m.get();
                  else
                  {
                    float d = PVector.dist(pm, m);
                    if ((pm.x != m.x || pm.y != m.y) && d > maxD)
                    {
                      int n = int(d / maxD);
                      PVector tmp = PVector.sub(m, pm);
                      tmp.normalize();
                      tmp.mult(maxD);
                      PVector tmp2 = m.get();
                      for (int i = 0; i < n; i++)
                      {
                        tmp2.sub(tmp);
                        parts.add(new Part(tmp2, (int)random(0, 25), (int)random(50, 140), 0)); 
                      }
                    }
                  }
                  parts.add(new Part(m, (int)random(0, 25), (int)random(50, 140), 0));
                  pm = m.get();
                }
                nb = parts.size()-1;
                for (int i = nb; i > -1; i--)
                {
                  if (parts.get(i).display())
                  {
                   parts.remove(i);
                  }
                }
    
    
                pg.endDraw();
                image(pg, 0, 0);
    
    
    
                //Clipping Mask
               // image(img, 0, 0);
    
              }
    
              void mouseReleased()
              {
    
                pm = null;
              }
    
              class Part
              {
                float rad, c = random(.6, .8), theta = random(TWO_PI), nx, ny;
                int life, age, mod = (int)random(30, 40);
                PVector pos;
    
                Part(PVector p, int a, int l, float r)
                {
                  pos = p.get();
                  age = a;
                  life = l;
                  rad = r;
                }
    
                Boolean display()
                {
    
                  nx = noise(rootn.x + pos.x/500)-.5;
                  ny = noise(rootn.y + pos.y/500)-.5;
    
    
                  pos.add(new PVector(6*nx, 6*ny));
    
    
                  rad += cos(map(age, 0, life, 0, HALF_PI)) * c;
    
                  pg.stroke(100,0,0, 200 * sq(map(age, 0, life, 1, 0)));
                  pg.strokeWeight(rad);
    
                  pg.point(pos.x, pos.y);
    
                  if (age++ % mod == 0)//split the Part in two
                  {
                    toAdd.add(new Part(new PVector(pos.x + rad/3 * cos(theta), pos.y + rad/3 * sin(theta)), age, life, rad * random(.6, .8))); // size of smoke set here
                    toAdd.add(new Part(new PVector(pos.x - rad/3 * cos(theta), pos.y - rad/3 * sin(theta)), age, life, rad * random(.6, .8)));//.6
                    age = life+1;
                  }
                  return age > life;
                }
              }
    
  • _vk_vk
    edited October 2015

    Good. Could you fix the format of the new code?

    drop backticks. Leave an empty line before and after the code, highlight it and hit ctr o

  • Done, did not realize that the format was broken, sorry.

Sign In or Register to comment.