Help in Barnes-Hut (Gravity Simulation)

I would like to create a gravity simulation using a method that provides good efficiency (Barnes-Hut algorithm)

I found this link GitHub - liuchia/barnes-hut: love2d nbody simulation which has everything i need, it’s just in 2D
but since I don’t have much experience with programming I can’t make it work

I’ve already tried asking friends for help, using ChatGPT and searching the internet for something similar, but this code doesn’t seem to be very popular

Algorithm definition
Barnes-Hut is a fast algorithm for approximating the forces between particles in a large-scale gravitational system, such as stars or galaxies.
algorithm works by recursively dividing the system into smaller regions with Quadtree/Octree method, so the calculation goes from being between each particle, to a calculation concentrated in the center of mass of a region, improving the efficiency of the simulation

This is my code without octree:

local RunService = game:GetService("RunService")
local SimulationTimeStep = 1
local G = 1

local Body = {}
Body.__index = Body

function Body.new(mass, pos, vel, body)
    return setmetatable({
        mass = mass,
        pos = pos,
        vel = vel,
        body = body
    }, Body)
end

local simulatedObjects = {}
for i, body in ipairs(workspace.Folder:GetChildren()) do
    local mass = body:GetAttribute("mass")
    local pos = body.Position
    local vel = body:GetAttribute("velocity")
    simulatedObjects[i] = Body.new(mass, pos, vel, body)
end

RunService.Heartbeat:Connect(function(TimeStep)
    TimeStep *= SimulationTimeStep

    for i = 1, #simulatedObjects - 1 do
        for j = i + 1, #simulatedObjects do
            local BodyA, BodyB = simulatedObjects[i], simulatedObjects[j]
            local DirectionVector = BodyA.pos - BodyB.pos
            local DirectionNorml = DirectionVector.Unit
            local dist = DirectionVector.Magnitude
            local F = G * BodyA.mass * BodyB.mass / dist
            local acelerationA = F / BodyA.mass / dist
            local acelerationB = F / BodyB.mass / dist
            BodyA.vel -= DirectionNorml * (acelerationA * TimeStep)
            BodyB.vel += DirectionNorml * (acelerationB * TimeStep)
        end
    end

    for _, v in ipairs(simulatedObjects) do
        v.pos += v.vel * TimeStep
        v.body.Position = v.pos
    end
end)

That would be the desired result

1 Like

I managed to program this by studying part by part with the help of ChatGPT. For now it seems to work very well.


(the video is sped up)
Here is a link to my project in case anyone is interested:

I will be updating

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.