# Mutual attraction of objects

**URL:** <https://discourse.processing.org/t/mutual-attraction-of-objects/10985>\
**Category:** Coding Questions\
**Created:** [May 7, 2019, 3:07am UTC](https://discourse.processing.org/t/mutual-attraction-of-objects/10985 "2019-05-07T03:07:25Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Capt.Sloth](https://avatars.discourse-cdn.com/v4/letter/c/4af34b/32.png) [@Capt.Sloth](https://discourse.processing.org/u/Capt.Sloth)\
**Post date:** [May 7, 2019, 3:07am UTC](https://discourse.processing.org/t/mutual-attraction-of-objects/10985/1 "2019-05-07T03:07:25Z")

</div>

Hello,  
I am trying to take a different approach and use functions instead of classes to recreate the mutual attraction sketch from Nature of code (ch2.08 to be specific).I have taken a different approach,I am confident the basics do work since i’m able to get a sphere attract itself to the mouse pointer and follow it around.

I tried to use the nested Loop method in a different manner but the results are completely off.The circles almost teleport to the top left corner (0,0).It most like is a logical error on my part and any help will greatly be appreciated.

The reason i added the netForce() function is so that i can easily switch between having multiple circles follow the mouse pointer (this works ) and between the circles attracting each other(this doesn’t).

```auto
var particles = []; // various particles are stored in this array
function setup(){
    var width = windowWidth;
    var height = windowHeight;
    createCanvas(width, height);
    p = new particle();
    n = new netForce();
    //particles.push(p);

}
function mouseClicked(){
    p = new particle(); // when user clicks a new particle is formed
    particles.push(p); // particle is added to the array
 }
function draw(){
    background(200);
    for(i=0;i<particles.length;i++){
    particles[i].main();
    n.dir(particles[i]);
    
    
    }

}

function particle(){
    
    this.maxvelocity =5; ///
    this.maxforce = 0.5; //
    this.velocity = createVector(0,0);
    this.location = createVector(random(width),random(height)); // random initial location for each object
    this.targetMouse = 1; //1 = yes 0 = no(no results in mutual attraction which is borked)
    this.target = createVector();
    this.dir = createVector();
    
    this.origin = createVector(0,0);
    this.acceleration = createVector(0,0);
    
    this.display = function(){ // To display the object 
        
        circle(this.location.x,this.location.y,100);
    }

   this.acquireDir = function(direction){ // acquires the direction to the target

            this.dir = direction.sub(this.location);
            this.dir.normalize();    
            
            
            this.addForce(this.dir); // Pass the direction vector to be added to the acceleration
            
        }

   this.motion = function(){ // this function is responsible for providing the force
       
       
        this.velocity.add(this.acceleration);
        this.velocity.limit(this.maxvelocity);
        this.acceleration.mult(0);
    }

    this.addForce = function(force){
        this.acceleration.add(force);
    }

    this.update = function(){ // updates the location of the object
       
        this.location.add(this.velocity);
        
       
    }
    this.main = function(){   
        this.display();
        this.motion();
        this.update();
        
    }
    
}
function netForce(){
    
    this.dir = function(){
        
        
    
        if(particles[i].targetMouse == true){ // This if statement works as expectec
            //particles[i].target = createVector(mouseX,mouseY);
            this.mouse = createVector(mouseX,mouseY); // The target is the mouse only if targetMouse =1
            //particles[i].acquireDir(this.mouse);
            particles[i].target = this.mouse;
            particles[i].acquireDir(particles[i].target);
        
        }

        if(particles[i].targetMouse == false){ // Mutual repulsion // this doesn't work
             for(j=0;j<particles.length;j++){
                if(i!=j){
                particles[i].acquireDir(particles[j].location);
             }
            }
        }
    }
    }

```

[p5.js online editor version of the code](https://editor.p5js.org/philip.mathew1998@gmail.com/sketches/Es_4kjINS)

you need to change the value of targetMouse = 0 in particle function,this is when mutual attraction is supposed to take place.Any advice or tips will be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)\
**Post date:** [May 7, 2019, 4:04am UTC](https://discourse.processing.org/t/mutual-attraction-of-objects/10985/2 "2019-05-07T04:04:54Z")

</div>

there are a few problems with your code. the main problem is you’re subtracting the location from the direction var you pass into your acquireDir function. i made some adjustments and it now works as it should i believe.

```auto
var netForce;
var particles = []; // various particles are stored in this array
function setup() {
  var width = windowWidth;
  var height = windowHeight;
  createCanvas(width, height);
  netForce = new NetForce();
}

function mouseClicked() {
  p = new particle(); // when user clicks a new particle is formed
  particles.push(p); // particle is added to the array
}

function draw() {
  background(200);
  for (i = 0; i < particles.length; i++) {
    var p1 = particles[i];
    p1.main();
    netForce.dir(p1);
  }
}

function particle() {
  this.maxvelocity = 5; ///
  this.maxforce = 0.5; //
  this.velocity = createVector(0, 0);
  this.location = createVector(random(width), random(height)); // random initial location for each object
  this.targetMouse = 0; //1 = yes 0 = no(no results in mutual attraction which is borked)
  this.target = createVector();
  this.dir = createVector();

  this.origin = createVector(0, 0);
  this.acceleration = createVector(0, 0);

  this.display = function() { // To display the object 
    circle(this.location.x, this.location.y, 100);
  }

  this.acquireDir = function(direction) { // acquires the direction to the target

    this.dir = p5.Vector.sub(direction, this.location);
    this.dir.normalize();

    this.addForce(this.dir); // Pass the direction vector to be added to the acceleration
  }

  this.addForce = function(force) {
    this.acceleration.add(force);
  }

  this.update = function() { // updates the location of the object
    this.velocity.add(this.acceleration);
    this.velocity.limit(this.maxvelocity);
    this.acceleration.mult(0);
    this.location.add(this.velocity);
  }
  this.main = function() {
    this.update();
    this.display();
  }
}

function NetForce() {
  this.dir = function() {
    for (var i = 0; i < particles.length; i++) {
      var p1 = particles[i];
      if (p1.targetMouse == true) { // This if statement works as expectec
        var mv = createVector(mouseX, mouseY); // The target is the mouse only if targetMouse =1
        p1.acquireDir(mv);
      }
      else { // Mutual repulsion // this doesn't work          
        for (var j = 0; j < particles.length; j++) {
          if (i === j) continue;
          var p2 = particles[j];
          
          p1.acquireDir(p2.location);
        }
      }
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![Capt.Sloth](https://avatars.discourse-cdn.com/v4/letter/c/4af34b/32.png) [@Capt.Sloth](https://discourse.processing.org/u/Capt.Sloth)\
**Post date:** [May 7, 2019, 4:56am UTC](https://discourse.processing.org/t/mutual-attraction-of-objects/10985/3 "2019-05-07T04:56:25Z")

</div>

Thanks a lot, It finally runs as intended.

```auto
this.dir = direction.sub(this.location);

```

```auto
this.dir = p5.Vector.sub(direction, this.location);

```

Is the first piece of code wrong as it stores the vector(location - drection) in the variable this.dir rather than (direction - location) and i might be wrong but doesn’t the second line of code return the subtracted value which is stored in this.dir or does using p5.Vector.sub work differently?  
Thanks a lot for the help 😀

---

<div class="post-metadata">

**Author:** ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)\
**Post date:** [May 7, 2019, 5:03am UTC](https://discourse.processing.org/t/mutual-attraction-of-objects/10985/4 "2019-05-07T05:03:06Z")

</div>

taken from the p5.Vector [source](https://github.com/processing/p5.js/blob/master/src/math/p5.Vector.js)

> Subtracts x, y, and z components from a vector, subtracts one vector from  
> another, or subtracts two independent vectors. The version of the method  
> that subtracts two vectors is a static method and returns a p5.Vector, the  
> other acts directly on the vector. See the examples for more context.

---

<div class="post-metadata">

**Author:** ![Capt.Sloth](https://avatars.discourse-cdn.com/v4/letter/c/4af34b/32.png) [@Capt.Sloth](https://discourse.processing.org/u/Capt.Sloth)\
**Post date:** [May 7, 2019, 5:13am UTC](https://discourse.processing.org/t/mutual-attraction-of-objects/10985/5 "2019-05-07T05:13:04Z")

</div>

Ahhh, That makes sense.Thanks
