Outputting Multiple Vector Distances

edited January 2017 in Questions about Code

So I've got this kinda gravity simulation going where I'm creating a load of movers/planets with different masses that attract everything else in the system and I want it to output the distance between each mover/planet. I create a function for the distance, the same used in the gravity force function, and it works for one distance but not for the other. Can't see why it'll only list one distance, any help would be great!

int pAmnt = 2;   //Amount of planets(movers)
int dAmnt = (pAmnt*pAmnt)-pAmnt;  //Amount of distances

Mover[] movers = new Mover[pAmnt];
float [] distance = new float [dAmnt];

void setup() {
  size(1200, 800);
  for (int i=0; i< movers.length; i++) {
    movers[i] = new Mover(random(0.1, 4), random(width), random(height), random(4)-2, random(4)-2, random(2)-1, r         random(2)-1, i);
  }
}

void draw() {
  background(255);

  for (int i=0; i < movers.length; i++) {
    for (int j=0; j < movers.length; j++) {
      if (i !=j) {
        int k = 0;
        PVector force = movers[j].attract(movers[i]);  //Creates the attraction force
        distance[k] = movers[j].distance(movers[i]);   //Applies a distance calculation
        movers[i].applyForce(force);

        println(distance);   //Lists the distances
        k += 1;  //Increases the array
      }
    }
    movers[i].update();
    movers[i].display();
  }
}

class Mover {
  float mass;
  PVector location;
  PVector velocity;
  PVector acceleration;
  float G = 10;
  int number;

  Mover(float m, float x, float y, float vx, float vy, float ax, float ay, int n) {
    location = new PVector(x, y);
    velocity = new PVector(vx, vy);
    acceleration = new PVector(ax, ay);
    mass=m;
    number=n;
  }

  void applyForce(PVector force) {
    PVector f = PVector.div(force, mass);
    acceleration.add(f);
  }

  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    acceleration.mult(0);
  }

  float distance(Mover m) {
    PVector distanceV = PVector.sub(location, m.location);
    float distance = distanceV.mag();
    return distance;
  }

  void display() {
    pushMatrix();

    translate(location.x,location.y);
    stroke(0);
    fill(175);
    ellipse(0, 0, mass*16, mass*16);
    fill(0);
    text(number, mass*16+5, mass*16-5);

    popMatrix();

  }

  PVector attract(Mover m) {
    PVector force = PVector.sub(location, m.location);
    float distance = force.mag();
    distance = constrain(distance, 5.0, 25.0);
    force.normalize();

    float strength = (G * mass * m.mass) / (distance * distance);
    force.mult(strength);
    return force;
  }
}

Answers

  • typo in line 10?

    k += 1 in line 26 does nothing because you initialise it to 0 in line 20 - within the same block inside the inner loop.

  • Hello @CVaughan

    I put you some code here which works, of course isn't what you're working about, bus it is for a solar system.

    Anyway I give another link which work with classes, maybe is more complete than this one here...

    http://learningprocessing.com/exercises/chp14/exercise-14-10-solar-system-moons

    or this one

    https://disipio.wordpress.com/2012/12/31/simulate-the-solar-system-with-processing/

    float angPlanet1 = 0.0,
          angPlanet2 = PI/3.0,
          angPlanet3 = 2.0*PI/3.0,
          angMoon1 = 0.0,
          angMoon2 = PI;
    void setup()
    {
      size(400, 400);
      stroke(255);
      frameRate(30);
    }
    void draw()
    {
      background(0);
      // The sun is located in the center(0,0)
      translate(width/2, height/2);
      // Sol
      fill(#F1FA03); 
      ellipse(0, 0, 20, 20);
      pushMatrix();
      // Planet 1
      rotate(angPlanet1 += 0.1);
      translate(width/2/4, 0);
        fill(#05FA03);
      ellipse(0, 0, 15, 15);
    
        // Planet 2
      popMatrix();
      pushMatrix();
      rotate(angPlanet2 += 0.05);
      translate(width/2/4*2, 0);
      fill(#0BA00A);
      ellipse(0, 0, 15, 15);
      // Moon 1
      pushMatrix();
      rotate(angMoon1 += 0.1);
      translate(width/2/4/3, 0);
      fill(#08E4FF);
      ellipse(0, 0, 6, 6);
      // Moon 2
      popMatrix();
      rotate(angMoon2 += 0.05);
      translate(width/2/4/3*2, 0);
      fill(#118998);
      ellipse(0, 0, 6, 6);
      // Moon 3
      popMatrix();
      rotate(angPlanet3 += 0.025);
      translate(width/2/4*3, 0);
      fill(#075806);
      ellipse(0, 0, 15, 15);
    }
    
  • apart from the k error (see above) :

    your for-loop compares every planet against every other planet.

    so number 0 gets compared with 1 and then 1 with 0. Bad.

    Instead say int j=i+1:

      for (int i=0; i < movers.length-1; i++) {
        for (int j=i+1; j < movers.length; j++) {
    

    here you go:

    int pAmnt = 2;   //Amount of planets(movers)
    int dAmnt = (pAmnt*pAmnt)-pAmnt;  //Amount of distances
    
    Mover[] movers = new Mover[pAmnt];
    float [] distance = new float [dAmnt];
    
    void setup() {
      size(1200, 800);
      for (int i=0; i< movers.length; i++) {
        movers[i] = new Mover(random(0.1, 4), random(width), random(height), random(4)-2, random(4)-2, random(2)-1, random(2)-1, i);
      }
    }
    
    void draw() {
      background(255);
    
      int k = 0;
      for (int i=0; i < movers.length-1; i++) {
        for (int j=i+1; j < movers.length; j++) {
          if (i != j) {
    
            PVector force = movers[j].attract(movers[i]);  //Creates the attraction force
            distance[k] = movers[j].distance(movers[i]);   //Applies a distance calculation
            movers[i].applyForce(force);
    
            println( "from " + i +" to " + j + " is "+ distance[k]);   //Lists the distances
            k += 1;  //Increases the array
          }
        }
        movers[i].update();
        movers[i].display();
      }
    }
    
    class Mover {
      float mass;
      PVector location;
      PVector velocity;
      PVector acceleration;
      float G = 10;
      int number;
    
      Mover(float m, float x, float y, float vx, float vy, float ax, float ay, int n) {
        location = new PVector(x, y);
        velocity = new PVector(vx, vy);
        acceleration = new PVector(ax, ay);
        mass=m;
        number=n;
      }
    
      void applyForce(PVector force) {
        PVector f = PVector.div(force, mass);
        acceleration.add(f);
      }
    
      void update() {
        velocity.add(acceleration);
        location.add(velocity);
        acceleration.mult(0);
      }
    
      float distance(Mover m) {
        PVector distanceV = PVector.sub(location, m.location);
        float distance = distanceV.mag();
        return distance;
      }
    
      void display() {
        pushMatrix();
    
        translate(location.x, location.y);
        stroke(0);
        fill(175);
        ellipse(0, 0, mass*16, mass*16);
        fill(0);
        text(number, mass*16+5, mass*16-5);
    
        popMatrix();
      }
    
      PVector attract(Mover m) {
        PVector force = PVector.sub(location, m.location);
        float distance = force.mag();
        distance = constrain(distance, 5.0, 25.0);
        force.normalize();
    
        float strength = (G * mass * m.mass) / (distance * distance);
        force.mult(strength);
        return force;
      }
    }
    
  • or using text() :

    int pAmnt = 5;   //Amount of planets(movers)
    int dAmnt = (pAmnt*pAmnt)-pAmnt;  //Amount of distances
    
    Mover[] movers = new Mover[pAmnt];
    float [] distance = new float [dAmnt];
    
    void setup() {
      size(1200, 800);
      for (int i=0; i< movers.length; i++) {
        movers[i] = new Mover(random(0.1, 4), random(width), random(height), random(4)-2, random(4)-2, random(2)-1, random(2)-1, i);
      }
    }
    
    void draw() {
      background(255);
    
      int k = 0;
      for (int i=0; i < movers.length-1; i++) {
        for (int j=i+1; j < movers.length; j++) {
          if (i != j) {
    
            PVector force = movers[j].attract(movers[i]);  //Creates the attraction force
            distance[k] = movers[j].distance(movers[i]);   //Applies a distance calculation
            movers[i].applyForce(force);
    
            // println( "from " + i +" to " + j + " is "+ distance[k]);   //Lists the distances
            text (  "from " + i +" to " + j + " is "+ distance[k], 19, 19+k*19);   //Lists the distances
            k += 1;  //Increases the array
          }
        }
        movers[i].update();
        movers[i].display();
      }
    }
    
    class Mover {
      float mass;
      PVector location;
      PVector velocity;
      PVector acceleration;
      float G = 10;
      int number;
    
      Mover(float m, float x, float y, float vx, float vy, float ax, float ay, int n) {
        location = new PVector(x, y);
        velocity = new PVector(vx, vy);
        acceleration = new PVector(ax, ay);
        mass=m;
        number=n;
      }
    
      void applyForce(PVector force) {
        PVector f = PVector.div(force, mass);
        acceleration.add(f);
      }
    
      void update() {
        velocity.add(acceleration);
        location.add(velocity);
        acceleration.mult(0);
      }
    
      float distance(Mover m) {
        PVector distanceV = PVector.sub(location, m.location);
        float distance = distanceV.mag();
        return distance;
      }
    
      void display() {
        pushMatrix();
    
        translate(location.x, location.y);
        stroke(0);
        fill(175);
        ellipse(0, 0, mass*16, mass*16);
        fill(0);
        text(number, mass*16+5, mass*16-5);
    
        popMatrix();
      }
    
      PVector attract(Mover m) {
        PVector force = PVector.sub(location, m.location);
        float distance = force.mag();
        distance = constrain(distance, 5.0, 25.0);
        force.normalize();
    
        float strength = (G * mass * m.mass) / (distance * distance);
        force.mult(strength);
        return force;
      }
    }
    
  • your for-loop compares every planet against every other planet. so number 0 gets compared with 1 and then 1 with 0. Bad.

    no, this is fine, depends what he's doing in the condition. if he's only updating item i then he'll need to do both 0,1 and 1,0 so that both item 0 and 1 get updated.

    in this case he appears to be only updating movers[i] so it's ok (this maybe not the most efficient thing in the world and could cause errors because the second item is compared with the first version AFTER it's been modified but...)

  • if pAmnt was in the 10s of thousands i might be more worried but as it's only 2...

  • yeah... but isn't he applying all forces twice to each planet? That must be wrong...?

  • Why twice? Isn't he just looping over the planets and applying the forces for all the other planets to each one?

    Tbh, I only ran it long enough to confirm the k bug - the window was too large for my laptop so I couldn't really see what it was doing / meant to do.

  • Hey guys thanks for the feedback,

    The k bug was indeed the issue. Thanks for the suggestions with i+1 and the text have included that too, for what I'm aiming to do this all the functionality I require!

  • IMO, the i+1 is an error.

Sign In or Register to comment.