"Gravity well" in Box2D
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
 emanevitaerc
 Prole
 Posts: 16
 Joined: Sun Mar 13, 2016 7:21 am
"Gravity well" in Box2D
In a very crude space simulation using Love's physics, is there a way to roughly implement the attraction of bodies to each other based on their mass and density? I know using the world's gravity wouldn't make any sense since it's a single direction imposed on every body within it; all I'm really looking to do is have bodies have an attraction to the center of mass of other nearby bodies. Would it take too much processing power, or are there other problems that just make it impractical?
On a somewhat unrelated note, I think more physics tutorials on the wiki would be nice. The only one up right now is a decent introduction, but doesn't even begin to cover all the functionality.
On a somewhat unrelated note, I think more physics tutorials on the wiki would be nice. The only one up right now is a decent introduction, but doesn't even begin to cover all the functionality.

 Citizen
 Posts: 87
 Joined: Tue Dec 30, 2014 6:07 pm
Re: "Gravity well" in Box2D
Not too sure about how you implement it into Love's physics but the equation for gravitational force in real life is fairly simple
F = (GMm)/(r^2)
where G is a constant and M and m are the two point masses where m orbits M and r is the orbit distance (density doesn't matter). For something like Pluto and its moons this formula doesn't work because the moons and Pluto are similar enough in mass that the moons have a noticeable pull on Pluto, but for bodies where a moving small one orbits a stationary one you should find this works well.
F = (GMm)/(r^2)
where G is a constant and M and m are the two point masses where m orbits M and r is the orbit distance (density doesn't matter). For something like Pluto and its moons this formula doesn't work because the moons and Pluto are similar enough in mass that the moons have a noticeable pull on Pluto, but for bodies where a moving small one orbits a stationary one you should find this works well.
Re: "Gravity well" in Box2D
Tutorials are sparse since there are tons of tutorials for "regular" box2d that can be followed exactly in the Lua/LÖVE binding as well.emanevitaerc wrote:In a very crude space simulation using Love's physics, is there a way to roughly implement the attraction of bodies to each other based on their mass and density? I know using the world's gravity wouldn't make any sense since it's a single direction imposed on every body within it; all I'm really looking to do is have bodies have an attraction to the center of mass of other nearby bodies. Would it take too much processing power, or are there other problems that just make it impractical?
On a somewhat unrelated note, I think more physics tutorials on the wiki would be nice. The only one up right now is a decent introduction, but doesn't even begin to cover all the functionality.
@Skeletonfx: why would it not work? The Earth's and the moon's mass are also both significant enough for the two to be rotating around a common center thats quite a bit off from the earth's center point. The calcualtion should work regardless.
You just need to calculate the force working between each pair of bodies every frame and apply it to each of them.

 Citizen
 Posts: 87
 Joined: Tue Dec 30, 2014 6:07 pm
Re: "Gravity well" in Box2D
I should have said it wouldn't work as simply because the bigger object would move non negligibly due to the force on it (which doesn't happen for Earthmoon) and so radius could change
https://en.wikipedia.org/wiki/Newton%27 ... odern_form
If you're willing to loop over every object and apply the force for and to every object then the physics won't be wrong.
Why doesn't it happen for EarthMoon?
Using data grabbed off wikipedia
Mass of Earth = 5.972 × 10^24 kg
Mass of Moon = 7.348 × 10^22 kg
G: 6.674×10^−11
Avg orbit radius of Moon around Earth (it's an ellipse) 385000 km
Force =  (G * M * m) / r^2
= 1.97*10^20
Acceleration of Earth due to force = F / m = (1.97*10^20) / (5.972 × 10^24) = 0.000033 ms^2 (2sf)
Negligible
https://en.wikipedia.org/wiki/Newton%27 ... odern_form
If you're willing to loop over every object and apply the force for and to every object then the physics won't be wrong.
Why doesn't it happen for EarthMoon?
Using data grabbed off wikipedia
Mass of Earth = 5.972 × 10^24 kg
Mass of Moon = 7.348 × 10^22 kg
G: 6.674×10^−11
Avg orbit radius of Moon around Earth (it's an ellipse) 385000 km
Force =  (G * M * m) / r^2
= 1.97*10^20
Acceleration of Earth due to force = F / m = (1.97*10^20) / (5.972 × 10^24) = 0.000033 ms^2 (2sf)
Negligible
Re: "Gravity well" in Box2D
Here's something that looks fairly decent.
I'm not sure how realistic it is (maybe someone more experienced can comment on that), but something along these lines in love.update should be alright for a game where all bodies are attracted to all other bodies.
Code: Select all
local bodies = world:getBodyList()
local G = 0.0667
for _, b1 in ipairs(bodies) do
local vx, vy = 0, 0
for _, b2 in ipairs(bodies) do
if b2 ~= b1 then
local x1, y1 = b1:getWorldCenter()
local x2, y2 = b2:getWorldCenter()
local m2 = b2:getMass()
vx = vx + (x2  x1) * m2
vy = vy + (y2  y1) * m2
end
end
b1:applyForce(vx * G, vy * G)
end
 emanevitaerc
 Prole
 Posts: 16
 Joined: Sun Mar 13, 2016 7:21 am
Re: "Gravity well" in Box2D
This looks to be exactly what I'm looking for, thank you. Maybe it can be optimized by excluding inconsequentially small bodies and just keeping a table for bigger objects.airstruck wrote:Here's something that looks fairly decent.
I'm not sure how realistic it is (maybe someone more experienced can comment on that), but something along these lines in love.update should be alright for a game where all bodies are attracted to all other bodies.Code: Select all
snippy snip
Re: "Gravity well" in Box2D
Of course you'll still need to pull small bodies towards big ones, so you might need two tables. Also b1:getWorldCenter() should have been done outside of that inner loop.emanevitaerc wrote:Maybe it can be optimized by excluding inconsequentially small bodies and just keeping a table for bigger objects.
 emanevitaerc
 Prole
 Posts: 16
 Joined: Sun Mar 13, 2016 7:21 am
Re: "Gravity well" in Box2D
Righty o, thanks for the help.airstruck wrote:Of course you'll still need to pull small bodies towards big ones, so you might need two tables. Also b1:getWorldCenter() should have been done outside of that inner loop.emanevitaerc wrote:Maybe it can be optimized by excluding inconsequentially small bodies and just keeping a table for bigger objects.
Re: "Gravity well" in Box2D
It just occurred to me that you might be able to do this in O(n) time by calculating the center of mass for all bodies and then adjusting for each body's own position and mass before you apply the force to it. Completely untested, just an idea. Someone with more physics experience might be able to comment.
Re: "Gravity well" in Box2D
Not a bad example by airstruck, but a more optimal approach might be to handle the gravity between PAIRS of bodies so:
Note that the number of pairs increases rapidly so it would only be practical for up to 200300 bodies.
G*m1 could be moved outside of the inner loop too.
Also, make sure you set a mass for your static bodies so it's not 0.
Code: Select all
for i = 1, #bodies do
local m1 = bodies[i]:getMass()
local x1, y1 = b1:getWorldCenter()
for j = i + 1, #bodies do
 find the force of gravity between bodies[i] => bodies[j]
local m2 = bodies[j]:getMass()
local x2, y2 = b2:getWorldCenter()
local dx, dy = x1  x2, y1  y2  distance vector
local dsq = dx*dx + dy*dy  distance squared
assert(dsq > 0, "singularity :)")
local f = G*m1*m2/dsq  force
local idf = 1/math.sqrt(dsq)*f  inverse distance*force
local gx, gy = dx*idf, dy*idf  force vector
 apply force to the pair i, j
bodies[i]:applyForce(gx, gy)
bodies[j]:applyForce(gx, gy)
end
end
G*m1 could be moved outside of the inner loop too.
Also, make sure you set a mass for your static bodies so it's not 0.
Who is online
Users browsing this forum: Google [Bot] and 9 guests