# How Can I Control Vectors via Grayscale Values of An Image?

**URL:** https://discourse.processing.org/t/how-can-i-control-vectors-via-grayscale-values-of-an-image/19905
**Category:** Coding Questions
**Tags:** homework
**Created:** [April 18, 2020, 8:55pm UTC](https://discourse.processing.org/t/how-can-i-control-vectors-via-grayscale-values-of-an-image/19905 "2020-04-18T20:55:35Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Peyton](https://avatars.discourse-cdn.com/v4/letter/p/e79b87/32.png) [@Peyton](https://discourse.processing.org/u/Peyton)
#### Post date: [April 18, 2020, 8:55pm UTC](https://discourse.processing.org/t/how-can-i-control-vectors-via-grayscale-values-of-an-image/19905/1 "2020-04-18T20:55:35Z")

</div>

Hi! I am obsessed with the look of Perlin noise, and decided to try to use it (and Processing) for the first time, to design a piece for a design project. At the moment, I have a flowfield that creates some awesome looking Perlin noise, but my aim is to get a referenced image displayed using Perlin noise.

Is there a way to control the vectors in the flowfield via grayscale values so that the particles start to accumulate according to the darkness/lightness of the photo? I’ve attached an example of what I am hoping to accomplish.

 ![GenerativePortrait1](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/5c299c2a967e266f114e5d11a1519e4bdfc1de11.png)

I have been watching some fantastic tutorials online (from The Coding Train, thedotisblack creative coding, and more) but have not found any that could help me with this. I was wondering if anyone could help me or point me in the direction of some tutorials (if there are any) that pertain to this.

Thank you so much in advance.

```auto
FlowField flowfield;
ArrayList<Particle> particles;

boolean debug = false;
boolean recording = false;

void setup() {
  size(1200, 800);
  
  flowfield = new FlowField(10);
  flowfield.update();

  particles = new ArrayList<Particle>();
  for (int i = 0; i < 10000; i++) {
    PVector start = new PVector(random(width), random(height));
    particles.add(new Particle(start, random(2, 7)));
  }
  background(0);
  colorMode (HSB, 360, 100, 100);
}

void keyPressed() {
    if (key == 'r' || key == 'R') {
      recording = !recording;
    }
}

void draw() {
  flowfield.update();
  
  if (debug) flowfield.display();
  
  for (Particle p : particles) {
    p.follow(flowfield);
    p.run();
  }
  if (recording) {
    saveFrame("output/frame_####.png");
  }
}

public class FlowField {
  PVector[] vectors;
  int cols, rows;
  float inc = 0.1;
  float zoff = 0;
  int scl;
  
  FlowField(int res) {
    scl = res;
    cols = floor(width / res) + 1;
    rows = floor(height / res) + 1;
    vectors = new PVector[cols * rows];
  }
  void update() {
    float xoff = 0;
    for (int y = 0; y < rows; y++) { 
      float yoff = 0;
      for (int x = 0; x < cols; x++) {
        float angle = noise(xoff, yoff, zoff) * TWO_PI * 0.35;
        
        PVector v = PVector.fromAngle(angle);
        v.setMag(1);
        int index = x + y * cols;
        vectors[index] = v;
       
        xoff += inc;
      }
      yoff += inc;
    }
    zoff += 0.0004;
  }
  void display() {
    for (int y = 0; y < rows; y++) { 
      for (int x = 0; x < cols; x++) {
        int index = x + y * cols;
        PVector v = vectors[index];
        
        stroke(HSB, 360, 360);
        strokeWeight(0.1);
        pushMatrix();
        translate(x * scl, y * scl);
        rotate(v.heading());
        line(0, 0, scl, 0);
        popMatrix();
      }
    }
  }
}

public class Particle {
  PVector pos;
  PVector vel;
  PVector acc;
  PVector previousPos;
  float maxSpeed;
   
  Particle(PVector start, float maxspeed) {
    maxSpeed = maxspeed;
    pos = start;
    vel = new PVector(0, 0);
    acc = new PVector(0, 0);
    previousPos = pos.copy();
  }
  void run() {
    update();
    edges();
    show();
  }
  void update() {
    pos.add(vel);
    vel.limit(maxSpeed);
    vel.add(acc);
    acc.mult(0);
  }
  void applyForce(PVector force) {
    acc.add(force); 
  }
  void show() {
    stroke(50, 360, 360, 5);
    strokeWeight(1);
    line(pos.x, pos.y, previousPos.x, previousPos.y);
    //point(pos.x, pos.y);
    updatePreviousPos();
  }
  void edges() {
    if (pos.x > width) {
      pos.x = 0;
      updatePreviousPos();
    }
    if (pos.x < 0) {
      pos.x = width;    
      updatePreviousPos();
    }
    if (pos.y > height) {
      pos.y = 0;
      updatePreviousPos();
    }
    if (pos.y < 0) {
      pos.y = height;
      updatePreviousPos();
    }
  }
  void updatePreviousPos() {
    this.previousPos.x = pos.x;
    this.previousPos.y = pos.y;
  }
  void follow(FlowField flowfield) {
    int x = floor(pos.x / flowfield.scl);
    int y = floor(pos.y / flowfield.scl);
    int index = x + y * flowfield.cols;
    
    PVector force = flowfield.vectors[index];
    applyForce(force);
  }
}

```
