From 6affe9d425a64303fb4820a6547054b9afe716f8 Mon Sep 17 00:00:00 2001 From: UndeadMaelys Date: Sun, 5 Jun 2022 19:22:37 +0200 Subject: [PATCH] time controls and merging --- body.lua | 43 ++++---- main.lua | 329 +++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 258 insertions(+), 114 deletions(-) diff --git a/body.lua b/body.lua index a25eccf..a5d3014 100644 --- a/body.lua +++ b/body.lua @@ -1,26 +1,29 @@ BodyList = {} Body = class(nil,{type=0}) -function newBody(pos,vel,mass,color) - local o = {} - - -- coordinates - o.x = pos[1] or 0 - o.y = pos[2] or 0 - o.z = pos[3] or 0 - -- velocities - o.vx = vel[1] or 0 - o.vy = vel[2] or 0 - o.vz = vel[3] or 0 - -- accceleration - o.ax = 0 - o.ay = 0 - o.az = 0 - -- mass - o.mass = mass - -- color - o.color = color - o.max_distance = 0 +function newBody(data) + local o = {} + -- coordinates + o.x = data.pos[1] or 0 + o.y = data.pos[2] or 0 + o.z = data.pos[3] or 0 + -- velocities + o.vx = data.vel[1] or 0 + o.vy = data.vel[2] or 0 + o.vz = data.vel[3] or 0 + -- accceleration + o.ax = 0 + o.ay = 0 + o.az = 0 + -- mass + o.mass = data.mass or 1 + -- size + o.size = data.size or VIEW.planet_size*math.sqrt(data.mass) + -- color + o.color = data.color or {1,1,1} + o.max_distance = 0 + -- origin + o.origin = data.origin or nil table.insert(BodyList,o) end diff --git a/main.lua b/main.lua index d1d5014..71010d0 100644 --- a/main.lua +++ b/main.lua @@ -1,98 +1,223 @@ - function love.load() --options love.graphics.setColor(1,1,1) love.graphics.setDefaultFilter("nearest") -- good pixel - SCREEN_WIDTH = love.graphics.getWidth() - SCREEN_HEIGHT = love.graphics.getHeight() - - -- simulation variables - CONST_G = 39.5 - CONST_S = 0.15 - - T = 0 - DT = 1/120 - TIME_SPEED = 0.25 - - VIEW = {} - VIEW.x = 0 - VIEW.y = 0 - VIEW.prints = {} - VIEW.orbit_prints = {} - - require "class" + SCREEN_WIDTH = love.graphics.getWidth() + SCREEN_HEIGHT = love.graphics.getHeight() + + require "class" require "body" + -- simulation variables + CONST_G = 39.5 + CONST_S = 0.15 + + -- time + T = 0 + DT = 1/60 + TIME_SPEED = 0.25 + CURR_TS = 0 + + -- view + VIEW = {} + VIEW.x = 0 + VIEW.y = 0 + VIEW.size = 104 + VIEW.planet_size = 40 + VIEW.prints = {} + VIEW.print_time = 1/4 + VIEW.orbit_prints = {} + VIEW.orbit_print_time = 1500 + VIEW.fixated = true + newBody( - {0, 0, 0}, - {0, 0, 0}, - 40000, - {1,0,0} + { + pos = {0, 0, 0}, + vel = {-0, 0, 0}, + mass = 40000, + color = {1,0,0} + } ) newBody( - {10000, 0, 0}, - {0, 100000, 0}, - 200, - {0,1,0} + { + pos = {10000, 0, 0}, + vel = {0, 100000, 0}, + mass = 200, + color = {0,1,0} + } ) newBody( - {20000, 0, 0}, - {0, 100000, 0}, - 400, - {0,0,1} + { + pos = {20000, 0, 0}, + vel = {0, 100000, 0}, + mass = 400, + color = {0,0,1} + } ) newBody( - {0, 20000, 0}, - {-200000, 0, 0}, - 300, - {0,1,1} + { + pos = {0, 20000, 0}, + vel = {-200000, 0, 0}, + mass = 3000, + color = {0,1,1} + } ) + newBody( + { + pos = {0, -20000, 0}, + vel = {200000, 0, 0}, + mass = 3000, + color = {0,1,1} + } + ) +end + +function love.keypressed(key) + if key == "space" then + if CURR_TS == 0 then + CURR_TS = TIME_SPEED + else + CURR_TS = 0 + end + end + if key == "up" or key == "right" then + CURR_TS = CURR_TS + 0.1 + end + if key == "down" or key == "left" then + CURR_TS = CURR_TS - 0.1 + end + CURR_TS = math.max(0, CURR_TS) + if key == "z" then + VIEW.fixated = not VIEW.fixated + end end function love.update(dt) - T = math.floor((T + DT * TIME_SPEED)*1000)/1000 - UpdateBodiesAcceleration() - UpdateBodiesVelocity(DT * TIME_SPEED) - UpdateBodiesPosition(DT * TIME_SPEED) + T = math.floor((T + DT * CURR_TS)*1000)/1000 + -- merge planets that collision + for i=1, #BodyList do + for j=i+1, #BodyList do + if BodyList[i] and BodyList[j] then + local body = BodyList[i] + local other_body = BodyList[j] + local size = body.size/VIEW.size + local other_size = VIEW.planet_size*math.sqrt(other_body.mass) + + if math.sqrt( + (other_body.x - body.x) * (other_body.x - body.x) + + (other_body.y - body.y) * (other_body.y - body.y) + + (other_body.z - body.z) * (other_body.z - body.z) + ) < (size + other_size) * 2 + then + print("matching ".. i .. " and " .. j) + print("original "..i.." pos {"..body.x..", "..body.y..", "..body.z.."}") + print("original "..i.." vel {"..body.vx..", "..body.vy..", "..body.vz.."}") + + print("original "..j.." pos {"..other_body.x..", "..other_body.y..", "..other_body.z.."}") + print("original "..j.." vel {"..other_body.vx..", "..other_body.vy..", "..other_body.vz.."}") + + local new_x = (body.x + other_body.x) / 2 + local new_y = (body.y + other_body.y) / 2 + local new_z = (body.z + other_body.z) / 2 + print("new pos {"..new_x..", "..new_y..", "..new_z.."}") + + local new_vx = (body.vx + other_body.vx) / 2 + local new_vy = (body.vy + other_body.vy) / 2 + local new_vz = (body.vz + other_body.vz) / 2 + print("new vel {"..new_vx..", "..new_vy..", "..new_vz.."}") + + local new_mass = body.mass + other_body.mass + print("new mass "..new_mass) + + local new_color_r = (body.color[1]+other_body.color[1])/2 + local new_color_g = (body.color[2]+other_body.color[2])/2 + local new_color_b = (body.color[3]+other_body.color[3])/2 + print("new color {"..new_color_r..", "..new_color_g..", "..new_color_b.."}") + + newBody( + { + pos = {new_x, new_y, new_z}, + vel = {new_vx, new_vy, new_vz}, + mass = new_mass, + color = {new_color_r,new_color_g,new_color_b} + } + ) + + BodyList[i] = nil + BodyList[j] = nil + end + end + end + end + + UpdateBodiesAcceleration() + UpdateBodiesVelocity(DT * CURR_TS) + UpdateBodiesPosition(DT * CURR_TS) + + -- get previous view offset + local pvx = VIEW.x + local pvy = VIEW.y + -- center camera on bigger one + local vm = 0 + for n, body in pairs(BodyList) do + if body.mass > vm then + vm = body.mass + VIEW.x = -body.x + VIEW.y = -body.y + end + end + -- adjust sizes to slowest mass + local vm = 0 + for n, body in pairs(BodyList) do + if body.max_distance >= vm then + vm = body.max_distance + VIEW.size = math.sqrt(body.max_distance) + end + end + if VIEW.size == 0 and #BodyList > 0 then + VIEW.fixated = false + VIEW.size = math.sqrt(BodyList[1].mass) + end + -- adjust orbit trails to the reference object + if VIEW.fixated then + for n, print in pairs(VIEW.orbit_prints) do + print.pos.x = print.pos.x - VIEW.x + pvx + print.pos.y = print.pos.y - VIEW.y + pvy + end + end + -- clean list of bodies + local bl = {} + for _, body in pairs(BodyList) do + if body then + table.insert(bl, body) + end + end + BodyList = bl end function love.draw() - -- center camera on bigger one - local vm = 0 - for n, body in pairs(BodyList) do - if body.mass > vm then - vm = body.mass - VIEW.x = -body.x - VIEW.y = -body.y - end - end - local vm = 0 - for n, body in pairs(BodyList) do - if body.max_distance > vm then - vm = body.max_distance - VIEW.size = math.sqrt(body.max_distance) - end - end - - love.graphics.setColor(1,1,1) - -- draw bodies - for n, body in pairs(BodyList) do - addPrint(body) - end - drawObitPrints() - drawPrints() - -- draw info - love.graphics.setColor(1,1,1) - love.graphics.print("x,y: " .. VIEW.x .. VIEW.y .. " size: " .. VIEW.size .. " T: ".. T) - for n, body in pairs(BodyList) do - love.graphics.setColor(body.color[1],body.color[2],body.color[3]) - love.graphics.print("mass: "..body.mass..", x,y: "..body.x..", "..body.y..", vx, vy:"..body.vx..", "..body.vy,0,15*n) - end + love.graphics.setColor(1,1,1) + -- draw bodies + for n, body in pairs(BodyList) do + addPrint(body) + end + drawObitPrints() + drawPrints() + -- draw info + love.graphics.setColor(1,1,1) + love.graphics.print("x,y: " .. VIEW.x .. VIEW.y .. " size: " .. VIEW.size .. " T: ".. T) + for n, body in pairs(BodyList) do + love.graphics.setColor(body.color[1],body.color[2],body.color[3]) + local TT = "" + if body.origin then + TT = "T: " .. body.origin.T + end + love.graphics.print("mass: "..body.mass..TT..", x,y: "..body.x..", "..body.y..", vx, vy:"..body.vx..", "..body.vy,0,15*n) + end end function addPrint(body) - VIEW.print_time = 10 table.insert(VIEW.prints,{ pos = { x = body.x, @@ -102,39 +227,55 @@ function addPrint(body) color = body.color, time = VIEW.print_time }) - VIEW.orbit_print_time = 1200 - local trail_color = { - (1 + body.color[1])/2, - (1 + body.color[2])/2, - (1 + body.color[3])/2 - } - table.insert(VIEW.orbit_prints,{ - pos = { - x = body.x, - y = body.y - }, - mass = 1, - color = trail_color, - time = VIEW.orbit_print_time - }) + local trail_color = { + (1 + body.color[1])/2, + (1 + body.color[2])/2, + (1 + body.color[3])/2 + } + + if CURRENT_TS ~= 0 then + table.insert(VIEW.orbit_prints,{ + pos = { + x = body.x, + y = body.y + }, + mass = 1, + color = trail_color, + time = VIEW.orbit_print_time + }) + end end function drawPrints() for n, print in pairs(VIEW.prints) do love.graphics.setColor(print.color[1],print.color[2],print.color[3],print.time/VIEW.print_time) - love.graphics.circle("line",(VIEW.x+print.pos.x)/VIEW.size+SCREEN_WIDTH/2,(VIEW.y+print.pos.y)/VIEW.size+SCREEN_HEIGHT/2,(print.time/VIEW.print_time)*math.sqrt(print.mass)*5/VIEW.size) - print.time = print.time - 1 - if print.time < 1 then VIEW.prints[n] = nil end + love.graphics.circle( + "line", + (VIEW.x+print.pos.x)/VIEW.size+SCREEN_WIDTH/2, + (VIEW.y+print.pos.y)/VIEW.size+SCREEN_HEIGHT/2, + VIEW.planet_size * math.sqrt(print.mass)/VIEW.size * (print.time/VIEW.print_time) + ) + print.time = print.time - CURR_TS + if print.time < 1 + or print.time > VIEW.print_time then + VIEW.prints[n] = nil + end end end - - function drawObitPrints() for n, print in pairs(VIEW.orbit_prints) do love.graphics.setColor(print.color[1],print.color[2],print.color[3],print.time/VIEW.orbit_print_time) - love.graphics.circle("line",(VIEW.x+print.pos.x)/VIEW.size+SCREEN_WIDTH/2,(VIEW.y+print.pos.y)/VIEW.size+SCREEN_HEIGHT/2,(print.time/VIEW.orbit_print_time)*print.mass/VIEW.size) - print.time = print.time - 1 - if print.time < 1 then VIEW.orbit_prints[n] = nil end + love.graphics.circle( + "line", + (VIEW.x+print.pos.x)/VIEW.size+SCREEN_WIDTH/2, + (VIEW.y+print.pos.y)/VIEW.size+SCREEN_HEIGHT/2, + print.mass/VIEW.size * (print.time/VIEW.orbit_print_time) + ) + print.time = print.time - CURR_TS + if print.time < 1 + or print.time > VIEW.orbit_print_time then + VIEW.orbit_prints[n] = nil + end end end \ No newline at end of file