Nikola
Nikola

Reputation: 43

Java gravity loop optimization

Why bodies seems broken on second loop example, am trying to optimize my planetary system to support more bodies.

for(Body body : bodies){
    PVector totalForce = new PVector();
    for(Body other : bodies){
        if(body != other){
            PVector fxy = body.attraction(other);
            totalForce.x += fxy.x;
            totalForce.y += fxy.y;
        }
    }

    body.vel.x += totalForce.x / body.mass * timestep;
    body.vel.y += totalForce.y / body.mass * timestep;
    body.pos.x += body.vel.x * timestep;
    body.pos.y += body.vel.y * timestep;
}

second loop where just one body is moving and it is moving in wrong directions

PVector totalForce = new PVector();
PVector fxy = new PVector();
for(int i = 0; i + 1 < bodies.size(); i++){
    Body body = bodies.get(i);
    Body other = bodies.get(i + 1);
    System.out.println(body + " " + other);
    fxy = body.attraction(other);
    totalForce.x += fxy.x;
    totalForce.y += fxy.y;
    body.vel.x += totalForce.x / body.mass * timestep;
    body.vel.y += totalForce.y / body.mass * timestep;
    body.pos.x += body.vel.x * timestep;
    body.pos.y += body.vel.y * timestep;
}

gravity example

Upvotes: 1

Views: 88

Answers (2)

Hyeonseo Yang
Hyeonseo Yang

Reputation: 1128

It seems that the code is not applying every forces affecting the body.

Body body = bodies.get(i);
Body other = bodies.get(i + 1);

These two lines are suspicious, and have to be thought over more.

Mathematically this wikipedia link and this SO community wiki may help you optimizing.

So, a possible candidate is:

n=num_of_bodies;
for(int i=0;i<n-1;++i)
{
    for(int j=i+1;j<n;++j)
    {
        final Body body=bodies.get(i);
        final Body other=bodies.get(j);
        PVector fxy = body.attraction(other);
        float c=timestep/body.mass;
        body.vel.x+=fxy.x*c;
        body.vel.y+=fxy.y*c;

        c=-timestep/other.mass;
        other.vel.x+=fxy.x*c;
        other.vel.y+=fxy.y*c;

    }
}
for(Body body:bodies)
{
    body.pos.x+=body.vel.x*timestep;
    body.pos.y+=body.vel.y*timestep;
}

The point of it is reducing repetition of calc performed to body and other. If indices are wrong please edit mine.

Upvotes: 1

OldCurmudgeon
OldCurmudgeon

Reputation: 65879

In your first sample you are examining every possible pair of bodies.

a,b,c - (a,b),(a,c),(b,c)

In your second example you are examining each neighboring body.

a,b,c - (a,b),(b,c)

Upvotes: 2

Related Questions