Array of Lines that move different to each other Perlin Noise


#1

I have a sketch that makes a multiple of vertex lines using beginShape(); and endShape();. They move using Perlin Noise. My problem is that I want each line to move differently while at this moment they all have the same movement.

Ive made a sketch originally in Processing and have been migrating it over to P5. It works as I want it to in Processing but not in p5.

Thanks in advance.

var lineCount = 10;

var lines = [];

function setup() {
createCanvas(720, 720);

for (var i = 0; i < lineCount; i++) {
lines[i] = new Lines(i, 0.5, 255, 0, 100, 255);

}
}

function draw () {
background(0);
translate(height/2, width/2);
for (var i = 0; i < lineCount; i++) {
lines[i].display();
}
}

function Lines(_rot, _inc, _r, _g, _b, _a) {

this.rot = _rot;
this.inc = _inc;
this.r = _r;
this.g = _g;
this.b = _b;
this.a = _a;
this.yoff = 0.0;

}

Lines.prototype.display = function() {
rotate(this.rot);
strokeWeight(2);
noFill();
this.c = color(this.r, this.g, this.b, this.a);
stroke(this.c);
beginShape();
this.xoff = 0.0;
for(this.x = 50; this.x < 250; this.x += 20){
this.y = map(noise(this.xoff+this.yoff), 0, 1, 50, 150);
vertex(this.x, this.y);
this.xoff += this.inc;
}
endShape();
this.yoff += 0.01;
}


#2

Hi! Nice sketch :slight_smile:

The way to get different values out of noise is to feed it different arguments. But currently, all your lines are getting the same arguments inside noise. For instance xoff changes along the line, but equally for all lines, and yoff increases between animation frames, but equally for all lines.
So how could you have a unique argument inside noise() for each line? Think of it as the “id”, or the “uniqueness” of each line :slight_smile: If you figure out I can tell how I would do it :slight_smile:


#3

Thanks Hamoid. Im not sure how to make them unique. I tried using push() and pop(), making different variables global in the sketch. Different ways to making the display() function. Just coming up blank. Thanks for the hint. Ill keep trying.


#4

I’ll try give another hint :slight_smile: if you run

println(noise(1), noise(2), noise(3));

you get 3 random numbers. If you run

println(noise(1), noise(2), noise(3));
println(noise(1), noise(2), noise(3));

You get the same 3 random numbers twice. That’s why you get the same lines many times.

But if you try this instead

println(noise(1), noise(2), noise(3));
println(noise(4), noise(5), noise(6));

you no longer get the same 3 numbers repeated.

This could be also written as

println(noise(1), noise(2), noise(3));
println(noise(1+3), noise(2+3), noise(3+3));

(so basically I added an offset of 3 to the first line).

And the same happens with multidimensional noise:

println(noise(1,5), noise(2,5), noise(3,5));
println(noise(1,5), noise(2,5), noise(3,5));

gets you the same 3 numbers two times. But you can do this

println(noise(1,5), noise(2,5), noise(3,5));
println(noise(1,6), noise(2,6), noise(3,6));

or

println(noise(1,5,0), noise(2,5,0), noise(3,5,0));
println(noise(1,5,1), noise(2,5,1), noise(3,5,1));

to get different values. Do you see the pattern? The idea is to make sure that you are not calling noise always with the same values for each line, otherwise you get the same line again and again.


#5

Thanks Again. Ive added a var to add a number that adds 1 each time the line is drawn called this.count. The lines are all different. Only the animation isn’t smooth like in my Processing sketch which makes it feel very jumpy. I’m presuming this is because this.x returns to 0 once the loop is complete. Not sure how to fix that but there you go.

Ive added the code to show how Ive changed the sketch.

Cheers.

var lineCount = 15;

var lines = [];

var l1;

function setup() {
createCanvas(720, 720);

for (var i = 0; i < lineCount; i++) {
lines[i] = new Lines(i, 0.05, i, 255, 0, 100, 100);

}
}

function draw () {
background(0);
translate(height/2, width/2);
for (var i = 0; i < lineCount; i++) {
lines[i].display();
}
}

function Lines( _rot, _inc, _count, _r, _g, _b, _a) {

this.rot = _rot;
this.inc = _inc;
this.count = _count;

this.r = _r;
this.g = _g;
this.b = _b;
this.a = _a;

this.yoff = 0.0;
}

Lines.prototype.display = function() {
rotate(this.rot);
strokeWeight(2);
noFill();
this.c = color(this.r, this.g, this.b, this.a);
stroke(this.c);
push();
beginShape();
this.xoff = 0.0;
for(this.x = 50; this.x < 200; this.x += 10){
this.y = map(noise(this.count + this.xoff, this.yoff), 0, 1, 0, 150);
vertex(this.x, this.y);
this.xoff += this.inc;
}
endShape();
pop();
this.yoff += 0.01;
}


#6

Hi! Now that you figured out, this is how I would do it: just replace

this.yoff = 0.0;

with

this.yoff = random(5);

This way each line has a unique starting point in the noise field, instead of all the lines starting at 0.0. The pauses in noise() will be out of sync for different lines, which will feel better. Then you can get rid of this.count :slight_smile:

It would be nice if you edit your post, copy the code, paste it in https://editor.p5js.org/ , choose edit > tidy code, paste it back in your post, and finally press the </> button so it’s highlighted beautifully, easier for everyone to read :slight_smile: