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

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.

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.

``````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));
}
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);
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() {
vel.limit(maxSpeed);
acc.mult(0);
}
void applyForce(PVector 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);
}
}
``````
1 Like