• fullscreen
  • particle.pde
  • vector_field_study_02.pde
  • class Particle {
    
      PVector position;
      PVector velocity;
      int timer;
    
    
      Particle (float x, float y) {
        position = new PVector(x, y);
        // velocity = new PVector();
        velocity = new PVector(0.01 - random(0.02), 0.01 - random(0.02));
        timer = int(random(120));
      }
    
    
      void Update() {
        int cellX = int(position.x);
        int cellY = int(position.y);
    
    
        flow[cellX][cellY].x = flow[cellX][cellY].x * 0.95 + velocity.x * 0.05;
        flow[cellX][cellY].y = flow[cellX][cellY].y * 0.95 + velocity.y * 0.05;
        density[cellX][cellY] += 0.1;
        flow[cellX][cellY].limit(1);
    
        velocity.x += 0.2 * flow[cellX][cellY].x;
        velocity.y += 0.2 * flow[cellX][cellY].y;
        //velocity.y += 0.01 * wind[cellY];
    
        velocity.mult(0.9);
    
        position.x = (position.x + velocity.x + resolutionX) % resolutionX;
        position.y = (position.y + velocity.y + resolutionY) % resolutionY;
    
        timer ++;
        if (timer > 240) {
          timer = int(random(120));
          position = new PVector(random(resolutionX), 
          random(resolutionY));
          velocity = new PVector(-1 + random(2), -1 + random(2));
        }
      }
    
    
      void Draw(float zoom) {
        stroke(0, min(255, int(255 * abs(velocity.x) / 0.2)),
          min(255, int(255 * abs(velocity.y / 0.2))));
        line(zoom * position.x, zoom * position.y,
        zoom * (position.x + velocity.x), 
        zoom * (position.y + velocity.y));
      }
    }
    
    
    int resolutionX = 192;
    int resolutionY = resolutionX / 2;
    PVector flow[][] = new PVector[resolutionX][resolutionY];
    float density[][] = new float[resolutionX][resolutionY];
    float wind[] = new float[resolutionY]; // horizontal bands
    int particleCount = 8192;
    Particle particle[] = new Particle[particleCount];
    int currentParticle;
    int oldMouseX;
    int oldMouseY;
    
    
    void setup() {
      size(960, 480);
      frameRate(60);
      for (int y = 0; y < resolutionY; y ++) {
        wind[y] = 1 * sin(4 * PI * y / resolutionY);
        for (int x = 0; x < resolutionX; x ++) {
          flow[x][y] = new PVector();
          //flow[x][y] = new PVector(0.2 - random(0.4), 0.2 - random(0.4));
        }
      }
      for (int i = 0; i < particleCount; i ++) {
        particle[i] = new Particle(random(resolutionX), 
          random(resolutionY));
      }
    }
    
    void draw() {
      fill(0);
      rect(0, 0, width, height);
      int zoom = min(width / resolutionX, height / resolutionY);
      
      for (int y = 0; y < resolutionY; y ++) {
        for (int x = 0; x < resolutionX; x ++) {
          density[x][y] = 0;
        }
      }
      
      // Particles?
      stroke(255);
      for (int i = 0; i < particleCount; i ++) {
        particle[i].Update();
        //particle[i].Draw(zoom);
      }
      
      noStroke();
      for (int y = 0; y < resolutionY; y ++) {
        for (int x = 0; x < resolutionX; x ++) {
          fill(
            /*min(255, int(255 * abs(flow[x][y].x) / 0.2)),
            min(255, int(255 * abs(flow[x][y].y / 0.2))),*/
            int(max(0, min(255, 255 * density[x][y]))));
          rect(x * zoom, y * zoom, zoom, zoom);
        }
      }
      
      // Randomization of flow
      //flow[int(random(resolutionX))][int(random(resolutionY))]
        //= new PVector(-1 + random(2), -1 + random(2));
        
      // Painting
      int cellX = mouseX / zoom;
      int cellY = mouseY / zoom;
      if (mousePressed) {
        for (int i = 0; i < 32; i ++) {
          particle[currentParticle] = new Particle(cellX, cellY);
          currentParticle = (currentParticle + 1) % particleCount;
        }
      }
      
      // Make mouse movement affect flow
      float dX = cellX - oldMouseX;
      float dY = cellY - oldMouseY;
      for (int y = -8; y < 8; y ++) {
        for (int x = -8; x < 8; x ++) {
          flow[max(0, min(resolutionX - 1, cellX + x))]
            [max(0, min(resolutionY - 1, cellY + y))].add
            (new PVector(dX, dY));
        }
      }
      oldMouseX = cellX;
      oldMouseY = cellY;
    }
    
    
    void keyPressed() {
      setup();
    }
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Loren Schmidt

    Vector Field Study 2

    Add to Faves Me Likey@! 7
    You must login/register to add this sketch to your favorites.

    This was my second attempt at doing a fluid simulation. Like the first, it uses particles combined with a vector field. I'm happy with the way that interacting with this one feels. I'm currently trying an approach that doesn't use particles at all- I'll upload that soon.

    Move the mouse to affect the vector field. Click to add particles. Press any key to reset.

    You need to login/register to comment.