Programming with Vectors (Objects moving towards each other)

edited June 2015 in Questions about Code

I want to simulate a river stream eventually. That means I want to have a board with a vector in each field. For now I'm trying to make the "red dots" go towards random vectors. Well, I know how to make the dots follow the mouse but not the vectors. I'd also like to visualize the vectors as black circles (for now, so i can check their position visually). I also used to have a vector class, where i already visualized the vectors as i wished to. Though it was an Array List and absolute -> not ideal for my goal. So i cut it out for now.

Thank you in advance :)

Here is my code:

ArrayList mikroplastikParticles; // set of Mikroplastik Particles
int numOfMikroplastikPerField = 1;
int boardSize = 7; // board to be filled with vectors
int board [][] = new int [boardSize][boardSize]; 
PVector vectorSet [][] = new PVector [boardSize][boardSize];
int cellWidth; // Size of the fields
final int mikroplastikSize = 10;
final int VectorSize = 10;
int randomVectorPosition;
float mikroplastikSpeed = 1.;

void setup() {
  // basic Setup
  size(700, 700);
  smooth();
  rectMode(CORNER);
  ellipseMode(CENTER);
  cellWidth = width/boardSize; // width of the cell dependens on the size of the board 
  mikroplastikParticles = new ArrayList();

  // visualization of the board (understanding purpose only)
  fill(255, 255, 255);
  stroke(0);
  for (int r = 0; r<boardSize; r++) {
    for (int c = 0; c<boardSize; c++) {  
      rect(r * cellWidth, c * cellWidth, cellWidth, cellWidth);
    }
  }

  // now we start to initialize the particles
  for (int r = 0; r<boardSize; r++) // we want to fill every single field
    for (int c = 0; c<boardSize; c++) 
      for (int anz = 0; anz < numOfMikroplastikPerField; anz++) // we can choose how many particles per field we want with "numOfMikroplastikPerField"
        mikroplastikParticles.add(new Mikroplastik(r*cellWidth+random(cellWidth), c*cellWidth+ random(cellWidth))); // mikroplastik per field gets added

  // setting up the vectors
  for (int x = 0; x<boardSize; x++) {
    for (int y = 0; y<boardSize; y++) {
      randomVectorPosition = (int)random(2);
      if (randomVectorPosition == 0)
      vectorSet[x][y] = new PVector(0, random(cellWidth));
      else
      vectorSet[x][y] = new PVector(random(cellWidth), 0);
    }
  }
}

void draw() {
  background(255);
  for (int i=0; i < boardSize*boardSize*numOfMikroplastikPerField; i++) { 
    Mikroplastik myMikroplastik = (Mikroplastik)mikroplastikParticles.get(i); // getting all vectors from the array
    myMikroplastik.display(); // assigning a "to do" for the vectors
  }
}

class Mikroplastik  { // the actual mikroplastik class

  PVector mikroplastik = new PVector(0, 0); // the mikroplastik is a vector object
  PVector sum = new PVector(0, 0);

  Mikroplastik(float tempX, float tempY) {
    mikroplastik.set(tempX, tempY);
  }

  void display() 
{ // how the mikroplastik looks like 
    fill(#FF0000);
    noStroke();
    ellipse(mikroplastik.x, mikroplastik.y, mikroplastikSize, mikroplastikSize);

    // PVector mouse = Vector.vector(tempX, tempY);
    PVector mouse = new PVector(mouseX, mouseY);
    mouse.sub(mikroplastik);
    mouse.mult(0.05);
    sum.add(mouse);
    sum.normalize();
    sum.mult(mikroplastikSpeed);
    mikroplastik.add(sum);

  }
}

Answers

  • Select the code you have posted. Open a new window in Processing. Paste it. Run it. Whoops! Can you fix it? We don't want to.

    Try posting a version of your code that actually runs.

  • OK fixed it. Sorry, I missed some important parts of the code when copying it :D

  • Answer ✓

    A vector is just a direction. There is no way to make a dot "go towards" a vector, because a vector doesn't have a position - it's just a direction. Do you mean you want the dots to move in the same direction as a vector if they're in a certain area? Something like this?

    class Zone {
      float px, py, r;
      PVector v;
      color c;
      Zone(int dummy){
        px = random(width);
        py = random(height);
        r = random(20,100);
        c = color(random(128,255),random(128,255),random(128,255));
        v = new PVector(random(-.1,.1),random(-.1,.1),0);
      }
      void draw(){
        noFill();
        stroke(c);
        strokeWeight(2);
        ellipse(px,py,2*r,2*r);
        pushMatrix();
        translate(px,py);
        line(0,0,v.x*r*10,v.y*r*10);
        popMatrix();
        strokeWeight(1);
      }
      boolean is_in_zone(float x, float y){
        return(dist(x,y,px,py) <= r);
      }
    }
    
    class Dot {
      PVector pos, vel, acc;
      int id;
      color c;
      Dot(int iid) {
        id = iid;
        pos = new PVector( random(width), random(height), 0 );
        vel = new PVector( random(-1,1), random(-1,1), 0 );
        acc = new PVector( 0, 0, 0 );
        c = color(196); //color(random(255), random(255), random(255));
      }
      void draw() {
        simulate();
        render();
      }
      void simulate() {
        acc.x = 0;
        acc.y = 0;
        for(int i=0; i<zones.size();i++){
          if( zones.get(i).is_in_zone(pos.x,pos.y) ){
            acc.add(zones.get(i).v);
          }
        }
        //vel.mult(.99);
        vel.limit(5);
        vel.add(acc);
        pos.add(vel);
        pos.x+=width;
        pos.x%=width;
        pos.y+=height;
        pos.y%=height;
      }
      void render() {
        fill(c);
        noStroke();
        ellipse(pos.x, pos.y, 10, 10);
      }
    }
    
    ArrayList<Dot> dots;
    ArrayList<Zone> zones;
    int num_dots = 100;
    int num_zones = 10;
    
    void setup() {
      size(600, 600);
      dots = new ArrayList();
      zones = new ArrayList();
      for (int i=0; i<num_dots; dots.add (new Dot (i++)));
      for (int i=0; i<num_zones; zones.add (new Zone (i++)));
    }
    
    void draw() {
      background(0);
      for (int i=0; i<zones.size (); zones.get(i++).draw());
      for (int i=0; i<dots.size (); dots.get(i++).draw());
    }
    
  • edited June 2015

    Yes that's pretty much what i meant :) . Since it was all self taught I had a little problem grasping the use of vectors in Processing. From school I remember them to be the shortest distance of to points - so I figured I could just create two points and then make them move towards each other (like i can make an objects follow the mouse) :D Well anyway. I can certainly work with what you presented. Thanks for you time ;) and this is what i made out of it (it's supposed to simulate the distribution of particles in water)

            ArrayList<Mikroplastik> mikroplastikParticles;
            ArrayList<Stream> streamDirections;
            int num_mikroplastikParticles = 1000;
            int boardSize = 20; // board to be filled with vectors
            int cellWidth; // Size of the fields
    
            void setup() {
              size(800, 800);
              rectMode(CORNER);
              ellipseMode(CENTER);
              cellWidth = width/boardSize; // width of the cell dependens on the size of the board 
              mikroplastikParticles = new ArrayList();
              streamDirections = new ArrayList();
    
              for (int i=0; i<num_mikroplastikParticles; mikroplastikParticles.add (new Mikroplastik (i++)));
    
              for (int x = 0; x < boardSize; x++)
              for (int y = 0; y < boardSize; y++)
              streamDirections.add (new Stream (x*cellWidth+cellWidth/2, y*cellWidth+cellWidth/2));
    
            }
    
            void draw() {
              background(0);
              for (int i=0; i<streamDirections.size (); streamDirections.get(i++).draw());
              for (int i=0; i<mikroplastikParticles.size (); mikroplastikParticles.get(i++).draw());
            }
    
            class Stream {
              float vectorXPos, vectorYPos, ratio;
              PVector directionVector;
              color c;
              Stream(float xPos, float yPos) {
                vectorXPos = xPos;
                vectorYPos = yPos;
                ratio = cellWidth/2;
                c = color(random(128,220),random(128,220),random(128,220));
                directionVector = new PVector(random(-.1, .1), random(-.1, .1), 0);
              }
    
              void draw() {
                /*
                noFill();
                stroke(c);
                strokeWeight(2);
                rect(vectorXPos-r, vectorYPos-r, 2*r, 2*r); 
                 pushMatrix();
                translate(vectorXPos,vectorYPos);
                line(0, 0, directionVector.x*r*10, +directionVector.y*r*10);
                strokeWeight(1);
                popMatrix();
                */
              }
              boolean is_in_zone(float x, float y) {
                return(dist(x, y, vectorXPos, vectorYPos) <= ratio);
              }
            }
    
            class Mikroplastik {
              PVector mikroplastikPos, speed, acceleration;
              int id;
              color c;
              Mikroplastik(int iid) {
                id = iid;
                mikroplastikPos = new PVector(random(width/2-50, width/2+50), random(height/2-50, height/2+50));
                speed = new PVector( random(-1, 1), random(-1, 1), 0 );
                acceleration = new PVector( 0, 0, 0 );
                c = color(#FF0000); 
              }
              void draw() {
                simulate();
                render();
              }
              void simulate() {
                acceleration.x = 0;
                acceleration.y = 0;
                for (int i=0; i<streamDirections.size (); i++) {
                  if ( streamDirections.get(i).is_in_zone(mikroplastikPos.x, mikroplastikPos.y) ) {
                    acceleration.add(streamDirections.get(i).directionVector);
                  }
                }
                speed.mult(.99);
                speed.limit(2);
                speed.add(acceleration);
                mikroplastikPos.add(speed);
              }
    
              void render() {   
                fill(c);
                noStroke();
                ellipse(mikroplastikPos.x, mikroplastikPos.y, 10, 10);
              }
            }
    
Sign In or Register to comment.