init
This commit is contained in:
commit
9554dcba22
123
src/main.moon
Normal file
123
src/main.moon
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
math.randomseed os.time!
|
||||||
|
w, h = love.graphics.getDimensions!
|
||||||
|
body_count = 1000
|
||||||
|
starting_area = 1000^2
|
||||||
|
percent_scale = 100 / body_count
|
||||||
|
radius_scale = 1/4
|
||||||
|
G = 100 -- 6.67408e-11
|
||||||
|
-- snapshot doubling ??
|
||||||
|
time, frame_time, sim_rate = 0, 1/60, 1/60
|
||||||
|
|
||||||
|
distance = (A, B) ->
|
||||||
|
local dx, dy
|
||||||
|
dx = A.x - B.x
|
||||||
|
dy = A.y - B.y
|
||||||
|
return math.sqrt dx * dx + dy * dy
|
||||||
|
|
||||||
|
gravity = (A, B) ->
|
||||||
|
local dx, dy, d2, F, theta, cos, sin
|
||||||
|
dx = A.x - B.x
|
||||||
|
dy = A.y - B.y
|
||||||
|
d2 = dx * dx + dy * dy
|
||||||
|
-- return if d2 == 0
|
||||||
|
if d2 <= (A.radius + B.radius)^2
|
||||||
|
return
|
||||||
|
F = G * A.mass * B.mass / d2
|
||||||
|
theta = math.atan2 dy, dx
|
||||||
|
cos = math.cos theta
|
||||||
|
sin = math.sin theta
|
||||||
|
A.vx -= (F / A.mass) * cos * sim_rate
|
||||||
|
A.vy -= (F / A.mass) * sin * sim_rate
|
||||||
|
B.vx += (F / B.mass) * cos * sim_rate
|
||||||
|
B.vy += (F / B.mass) * sin * sim_rate
|
||||||
|
|
||||||
|
class Body
|
||||||
|
new: =>
|
||||||
|
local d, theta
|
||||||
|
d = math.sqrt(starting_area) / 2
|
||||||
|
theta = math.random! * math.pi * 2
|
||||||
|
@x = math.random! * d * math.cos theta
|
||||||
|
@y = math.random! * d * math.sin theta
|
||||||
|
@vx = math.random! / d
|
||||||
|
@vy = math.random! / d
|
||||||
|
@mass = 1
|
||||||
|
@radius = @mass ^ radius_scale
|
||||||
|
|
||||||
|
bodies = {}
|
||||||
|
for i = 1, body_count
|
||||||
|
table.insert bodies, Body!
|
||||||
|
|
||||||
|
simulate = (bodies) ->
|
||||||
|
for i = 1, #bodies - 1, 2
|
||||||
|
for j = i + 1, #bodies
|
||||||
|
gravity(bodies[i], bodies[j])
|
||||||
|
|
||||||
|
for body in *bodies
|
||||||
|
body.x += body.vx * sim_rate
|
||||||
|
body.y += body.vy * sim_rate
|
||||||
|
|
||||||
|
invalid_bodies = {}
|
||||||
|
for i = #bodies, 2, -2
|
||||||
|
for j = i - 1, 1, -1
|
||||||
|
valid = true
|
||||||
|
for id in *invalid_bodies
|
||||||
|
if i == id or j == id
|
||||||
|
valid = false
|
||||||
|
if not valid
|
||||||
|
continue
|
||||||
|
A = bodies[i]
|
||||||
|
B = bodies[j]
|
||||||
|
-- print i, j
|
||||||
|
-- if not A
|
||||||
|
-- print i, j, #bodies
|
||||||
|
if distance(A, B) <= A.radius + B.radius
|
||||||
|
-- print "#{i} and #{j} collided!", distance(A, B), A.radius + B.radius
|
||||||
|
mass = A.mass + B.mass
|
||||||
|
radius = mass ^ radius_scale
|
||||||
|
-- print mass, radius
|
||||||
|
mx = (A.x * A.mass + B.x * B.mass) / mass
|
||||||
|
my = (A.y * A.mass + B.y * B.mass) / mass
|
||||||
|
vx = (A.vx * A.mass + B.vx * B.mass) / mass
|
||||||
|
vy = (A.vy * A.mass + B.vy * B.mass) / mass
|
||||||
|
A.mass = mass
|
||||||
|
A.radius = radius
|
||||||
|
A.x = mx
|
||||||
|
A.y = my
|
||||||
|
A.vx = vx
|
||||||
|
A.vy = vy
|
||||||
|
table.insert(invalid_bodies, j)
|
||||||
|
-- table.remove(bodies, j)
|
||||||
|
-- j += 1
|
||||||
|
|
||||||
|
table.sort invalid_bodies, (a, b) -> a > b
|
||||||
|
for id in *invalid_bodies
|
||||||
|
-- print id
|
||||||
|
table.remove bodies, id
|
||||||
|
-- print "end"
|
||||||
|
|
||||||
|
love.update = (dt) ->
|
||||||
|
simulate bodies
|
||||||
|
|
||||||
|
love.draw = ->
|
||||||
|
if #bodies > 1000
|
||||||
|
return
|
||||||
|
love.graphics.setColor 1, 1, 1, 0.25
|
||||||
|
love.graphics.line 0, h / 2, w, h / 2
|
||||||
|
love.graphics.line w / 2, 0, w / 2, h
|
||||||
|
love.graphics.setColor 1, 1, 1, 1
|
||||||
|
|
||||||
|
love.graphics.translate w / 2, h / 2
|
||||||
|
m, x, y = 0, 0, 0
|
||||||
|
for body in *bodies
|
||||||
|
if body.mass > m
|
||||||
|
m = body.mass
|
||||||
|
x = body.x
|
||||||
|
y = body.y
|
||||||
|
love.graphics.translate -x, -y
|
||||||
|
for body in *bodies
|
||||||
|
-- love.graphics.points body.x, body.y
|
||||||
|
love.graphics.circle "fill", body.x, body.y, body.radius
|
||||||
|
|
||||||
|
love.keypressed = (key) ->
|
||||||
|
if key == "escape"
|
||||||
|
love.event.quit!
|
Loading…
Reference in New Issue
Block a user