# Trailing and motion basics with p5js

Let’s start with a basic object in the middle of the screen. Let’s call it particle. We’ll give it a few properties and a few methods.

`var particle;`
```function setup() { createCanvas(windowWidth, windowHeight); particle = new Particle(); }```

```function draw() { background(51); particle.display();//places the object on canvas particle.update(); // updates object properties }```
``` //Particle constructor function Particle() { this.pos = createVector(width / 2, height / 2) //create a vector object to store coordinate componenents this.vel = createVector(0, 0); this.acc = createVector(0, 0);```
``` this.update = function() { this.vel.add(this.acc); this.pos.add(this.vel); }```
``` this.display = function() { strokeWeight(2); stroke("black");```
``` fill(255); ellipse(this.pos.x, this.pos.y, 48, 48); } }```

Now, let’s apply some movement, and add more particles to the program. I’m going to replicate Daniel Shiffman’s approach, with some variations. You can see his work The Nature of Code for a more in depth understanding of physics simulations.

```var particles = []; var mass;```
```function setup() { createCanvas(600, 400); } function mousePressed() { particles.push(new Particle(mouseX, mouseY,mass));//add a new partice on mousePressed }```

```function draw() { background(51); background("black"); var randomForce = createVector(random(-0.01,0.01), random(-0.01,0.01)); for (var i = 0; i < particles.length; i++) { if(mouseIsPressed){ particles[i].applyForce(randomForce); } particles[i].display(); //places the object on canvas particles[i].update(); // updates object properties particles[i].checkEdges();//check the paticle is within canvas //check if they particles are intersecting for (var j = 0; j < particles.length; j++){ if(i!=j && particles[i].intersects(particles[j])){ //print("intersects"); } }//end of loop j }//end of loop i```

```//Particle constructor function Particle(x, y) { //OBJECT PROPERTIES this.x = x; this.y = y; this.history = []; //we'll use this later to implement path trailing this.pos = createVector(x, y); //create a vector object to store coordinate componenents this.vel = createVector(0, 0); this.acc = createVector(0, 0); this.r = random(5, 10); this.radius = this.r; this.mass = this.r * 0.01;```

``` //OBJECT METHODS this.applyForce = function(force) { //MAKE A DUPLICATE OF THE FORCE, SO ITS ORIGINAL VALUE GETS PASSED TO ALL THE OBJECTS f = force.copy(); f.div(this.mass); // acc = force/mass this.acc = f; // newton's 2nd law of motion } this.update = function() { this.vel.add(this.acc); this.pos.add(this.vel); } ```
``` this.display = function() { strokeWeight(2); stroke("black"); fill(255); ellipse(this.pos.x, this.pos.y, this.radius * 2, this.radius * 2); } this.checkEdges = function() { if (this.pos.y > height) { this.vel.y *= -0.9; // A little dampening when hitting the bottom this.pos.y = height; } if (this.pos.y < 0) { this.vel.y *= -0.9; this.pos.y = 0; } if (this.pos.x < 0) { this.vel.x *= -0.9; this.pos.x = 0; } if (this.pos.x > width) { this.vel.x *= -0.9; this.pos.x = width; } } ```

```this.intersects = function(other) { var d = dist(this.pos.x, this.pos.y, other.pos.x, other.pos.y); if (d < this.radius + other.radius) { this.vel.x *= -1; other.vel.x *= -1; return true; } else { return false; } } }```

Click below to add some particles to the stage

Nice, now let’s add some extra functionality. We’ll create a path trailing effect, and also lets add the ability to remove objects from the canvas.

```var particles = []; var mass; function setup() { createCanvas(600, 400); } ```
``` function mousePressed() { particles.push(new Particle(mouseX, mouseY, mass)); }```
``` function keyPressed() { if (key == ' ') { particles.splice(0, 1); } } ```
``` function draw() { background(51); background("black"); var randomForce = createVector(random(-0.01, 0.01), random(-0.01, 0.01)); for (var i = 0; i < particles.length; i++) { if (mouseIsPressed) { particles[i].applyForce(randomForce); } particles[i].display(); //places the object on canvas particles[i].update(); // updates object properties particles[i].checkEdges(); //check the obejct is within canvas //check if they particles are intersecting for (var j = 0; j < particles.length; j++) { if (i != j && particles[i].intersects(particles[j])) { print("intersects"); } } //end of loop j } //end of loop i }```
``` //Particle constructor function Particle(x, y) { //OBJECT PROPERTIES this.x = x; this.y = y; this.history = []; //store the position history of each particle this.pos = createVector(x, y); //create a vector object to store coordinate componenents this.vel = createVector(0, 0); this.acc = createVector(0, 0); this.r = random(5, 10); this.radius = this.r; this.mass = this.r * 0.01;```
``` //OBJECT METHODS this.applyForce = function(force) { //MAKE A DUPLICATE OF THE FORCE, SO ITS ORIGINAL VALUE GETS PASSED TO ALL THE OBJECTS f = force.copy(); f.div(this.mass); // acc = force/mass this.acc = f; // newton's 2nd law of motion } this.update = function() { this.vel.add(this.acc); this.pos.add(this.vel);```
``` // trailing update for (i = 0; i < this.history.length; i++) { //add easing var easing = 0.2; var diffX = mouseX - this.history[i].x; var diffY = mouseY - this.history[i].y; //this.history[i].x += random(-1,1); //this.history[i].y+=random(-1,1); //this.history[i].x += diffX*easing; // this.history[i].y+=diffY*easing; this.history[i].x += random(diffX * easing); this.history[i].y += random(diffY * easing); } //store the current position into history[] var v = createVector(this.pos.x, this.pos.y); this.history.push(v); if (this.history.length > 100) { this.history.splice(0, 1); } } this.display = function() { strokeWeight(2); stroke("black"); fill(255); ellipse(this.pos.x, this.pos.y, this.radius * 2, this.radius * 2); //draw trailing beginShape(); strokeWeight(0.5); stroke("white"); noFill(); for (i = 0; i < this.history.length; i++) { var pos = this.history[i]; vertex(pos.x, pos.y); } endShape(); } ```
``` this.checkEdges = function() { if (this.pos.y > height) { this.vel.y *= -0.9; // A little dampening when hitting the bottom this.pos.y = height; } if (this.pos.y < 0) { this.vel.y *= -0.9; // A little dampening when hitting the top this.pos.y = 0; // at the border } if (this.pos.x < 0) { this.vel.x *= -0.9; // A little dampening when hitting the left this.pos.x = 0; // at the border } if (this.pos.x > width) { this.vel.x *= -0.9; // A little dampening when hitting the right this.pos.x = width; // at the border } } ```
``` this.intersects = function(other) { var d = dist(this.pos.x, this.pos.y, other.pos.x, other.pos.y); if (d < this.radius + other.radius) { this.vel.x *= -1; other.vel.x *= -1; return true; } else { return false; } } }```
Click below to add some particles to the stage, press space bar to remove them