How to replicate random vector movement along several axises

edited April 2017 in Questions about Code

Sorry about the confusing formulation of the title. I simply didn't know how to formulate what i'm asking in a short sentence.

I have code that increments a vector in a random direction every 3 seconds, with easing. What I need to figure out is how to do this with all the vectors in all the directions (x and y). Basically, i'm trying to have a shape where all the vectors of the shape move about randomly on the canvas.

float incr =0.2;
float xpos = 120;
int lastTimeCheck;
  int timeIntervalFlag = 3000; 
float x;
float y;
float easing = 0.05;

void setup() {

  size(500,707);
  stroke(255);
  lastTimeCheck = millis();

}





void draw() {
  background(49,48,48);
  float ran = random(2.3);

   if ( millis() > lastTimeCheck + timeIntervalFlag ) {
    lastTimeCheck = millis();
    if (ran > 1) {
    incr = 0.2;
    incr = incr*-1;

  }
  else if (ran < 1) {
    incr = 0.2;

  }
  }


  if (xpos < 0) {
    xpos = 0;

  }
xpos = xpos+incr;


  float targetX = xpos;
  float dx = targetX - x;
  x += dx * easing;

  beginShape();

    vertex(x,120);

    vertex(250,220);

    vertex(200,320);

    vertex(70,335);

  endShape();
  println(xpos);


}
Tagged:

Answers

  • You mean each vertex would change in different directions?

    Possible.

    But the shape would change its form / fly apart

  • Which is exactly what I want.

  • Iirc there is a tutorial on shapes where you can change vertex

    Or look at PShape maybe in the reference

  • edited April 2017

    I know how to change the position of the vertex, the problem is that if I want to do the same with 4 vertexes, I need 8 if/else statements, 8 random() variables and so forth to calculate and increment each x,y for each vertex.

    I was thinking maybe calculate in a loop and store each x and y in an array, and then call

    vertex(x[1], y[1])
    vertex(x[2], y[2])
    ....
    

    But I couldn't figure out how to do it.

  • Answer ✓

    For example,

    ArrayList<PVector> pts;
    
    void setup() {
    
      size(500, 707);
      stroke(255);
    
      pts=new ArrayList<PVector>();
      pts.add(new PVector(120, 120));
      pts.add(new PVector(250, 220));
      pts.add(new PVector(200, 320));
      pts.add(new PVector(70, 335));
    }
    
    void draw() {
      background(49, 48, 48);
    
    
      beginShape();
    
      for (PVector v : pts) {
        v.add(random(-5, 5), random(-5, 5));
        vertex(v.x, v.y);
      }
    
      endShape();
    }
    

    Kf

  • Found a way to do it with arrays:

    float[] time = new float[4];
    float[] x = new float[4];
    float[] incr = new float [4];
    void setup() {
      smooth();
      size(500, 707);
      stroke(255);
      lastTimeCheck = millis()/4;
      noFill();
    }
    
    void draw() {
      background(49, 48, 48);
    
      for (int i = 0; i < 4; i++) {
    
        float ran = random(2);
    
    
        if (ran > 1) {
          incr[i] = 0.5;
          incr[i] = incr[i]*-1;
        } else if (ran < 1) {
          incr[i] = 0.5;
        }
    
    
        println("i ran");
    
        if (x[i] > width || x[i] < 0) {
          incr[i] = incr[i]*-1;
        }
    
    
    
        x[i] = x[i] + incr[i];
    
    
    
        // println(x[i] + "loop" +i+ incr[i]);
      }
      beginShape();
      vertex(x[0]+20, 40);
      vertex(x[1]+20, width-40);
      vertex(x[2]+20, height-40);
      vertex(x[3]+20, 100);
    
    
      endShape(CLOSE);
    }
    
  • What's line 28 for? You probably wanted println(i + " " ran);.

  • Haha no sorry. It checks wether the if statement ran. "I ran" as in "The if statement ran". Should have deleted it.

  • edited April 2017 Answer ✓

    @fagerli -- below is a slight refactoring of your array-based approach. It defines the initial points in setup, makes the shape drawing logic a loop over n points, and separates the drifting logic as a function called on an array.

    // forum.processing.org/two/discussion/21778/how-to-replicate-random-vector-movement-along-several-axises
    // 2017-04-04
    
    float[] xs = new float[4];
    float[] ys = new float[4];
    
    void setup() {
      smooth();
      size(300, 300);
      stroke(255);
      noFill();
      frameRate(10);
      // define shape data
      xs[0] =  80;       ys[0] =  80;
      xs[1] = -80+width; ys[1] =  80;
      xs[2] = -80+width; ys[2] = -80+height;
      xs[3] =  80;       ys[3] = -80+height;
    }
    
    void draw() {
      background(48);
      // drift shape data
      driftArray(xs);
      driftArray(ys);
      // draw shape
      beginShape();
        for(int i=0; i<xs.length; i++){
          vertex(xs[i], ys[i]);
        }
      endShape(CLOSE);
    }
    
    // drift every member of an array
    void driftArray(float[] fs){
      for (int i = 0; i < fs.length; i++) {
        fs[i] = drift(fs[i]);
      }
    }
    
    // drift by -.5 or .5, constrain at edge of canvas
    float drift(float f){
      return constrain( f + (int)random(2)-.5, 0, width);
    }
    

    I might suggest:

    1. Take this approach further by using a PVector for each point and an ArrayList<PVector> to store your point list.

    2. Even further, you could use a PShape to define your shape and its built-in list of vertices, rather than recreating a new one in-place with beginShape each draw loop.

    Notice in particular that the demo sketch for PShape.setVertex() does exactly what you are doing in your demo sketch above! Try running the example code here:

  • Thank you! That's wonderful help. :)

Sign In or Register to comment.