One last one. This is tweaked a little to allow for scaling by adjusting the gravitational constant, and some fudging of scaling for the ellipses… mainly so that I could model a somewhat stable solar system.
I’ve left both planetary with a variable called setup - if you change it to 2 it’ll be the 2 planet 1 moon as previous
Also, if you change leaveTrails to true it will leave trails as the bodies move which will allow you to fine tune your orbits perhaps…
displayMode(FULLSCREEN)
--supportedOrientations(PORTRAIT)
function setup()
leaveTrails = false
if leaveTrails then
backingMode(RETAINED)
end
bodies = {}
setup = 1
if setup == 1 then
--solar system
--gravitation constant for scaling
G = .005
--initial planets
--sun
bodies[1] = { m= 40000, x = WIDTH/2, y= HEIGHT/2, dx=0, dy=0 }
--planets
bodies[2] = { m= 15, x = WIDTH/2, y= HEIGHT/2 - 65, dx= 1.8, dy = 0 }
bodies[3] = { m= 20, x = WIDTH/2, y= HEIGHT/2 - 100, dx=1.5, dy=0 }
bodies[4] = { m= 30, x = WIDTH/2, y= HEIGHT/2 - 150, dx=1.3, dy=0 }
bodies[5] = { m= 40, x = WIDTH/2, y= HEIGHT/2 - 180, dx=1.2, dy= 0}
bodies[6] = { m= 60, x = WIDTH/2, y= HEIGHT/2 - 300, dx=0.85, dy= 0 }
--moons
bodies[7] = { m= 0.1, x = WIDTH/2, y= HEIGHT/2 - 155, dx= 1.47, dy= 0 }
end
if setup == 2 then
--2 planets and a moon
G = 1
--initial planets
bodies[1] = { m = 400, x= 300, y= 500, dx = 1.4, dy = .4 }
bodies[2] = { m = 400, x= 300, y= 600, dx = -1.4, dy = -.4 }
bodies[3] = { m = 4, x = 300, y= 480, dx = -3.1, dy = .4 }
end
selectedBody = 1
end
function touched(touch)
if touch.state == BEGAN then
if touch.x > WIDTH - 100 and touch.y < HEIGHT - 85 and touch.y > HEIGHT - 125 then
--touched slower
bodies[selectedBody].dx = bodies[selectedBody].dx * .9
bodies[selectedBody].dy = bodies[selectedBody].dy * .9
elseif touch.x > WIDTH - 100 and touch.y < HEIGHT - 140 and touch.y > HEIGHT - 180 then
--touched faster
bodies[selectedBody].dx = bodies[selectedBody].dx * 1.1
bodies[selectedBody].dy = bodies[selectedBody].dy * 1.1
else
--change slected planet if touch is with 100 of it
closest = nil
dist = 100
for k,v in pairs(bodies) do
calcDist = math.sqrt((touch.x - v.x)^2+(touch.y - v.y)^2)
if calcDist < dist then
dist = calcDist
closest = k
end
end
if closest ~= nil then
selectedBody = closest
end
end
end
end
function draw()
if leaveTrails == false then
background(40,40,50)
end
strokeWidth(0)
fill(255)
applyGravity()
moveBodies()
-- plot bodies
for k,v in pairs(bodies) do
if selectedBody == k then
fill(255, 9, 0, 255)
else
fill(255,255,255,255)
end
ellipse(v.x, v.y, math.pow(v.m, .2)*2 + 2)
end
drawControl()
end
function drawControl()
fill(255,255,255,255)
text(string.format("Body: %d", selectedBody), WIDTH - 50, HEIGHT - 50)
fill(150,150,150,255)
rect(WIDTH - 100, HEIGHT - 125, 100, 40)
rect(WIDTH - 100, HEIGHT - 180, 100, 40)
fill(255,255,255,255)
text("slower", WIDTH - 50, HEIGHT - 105)
text("faster", WIDTH - 50, HEIGHT - 160)
v = math.sqrt(bodies[selectedBody].dx^2+bodies[selectedBody].dy^2)
text(string.format("Velocity: %f", v), WIDTH - 100, HEIGHT - 200)
end
function applyGravity()
for k,v in pairs(bodies) do
for k2,v2 in pairs(bodies) do
if k2 > k then
--gravity factor - this is distance facotring for gravity and trigonometry
d = 1 / math.pow(( (v.x - v2.x)^2 + (v.y - v2.y)^2), 1.5)
--adjust v velocity
v.dx = v.dx - (v.x - v2.x) * d * v2.m * G
v.dy = v.dy - (v.y - v2.y) * d * v2.m * G
--adjust v2 velocity
v2.dx = v2.dx - (v2.x - v.x) * d * v.m * G
v2.dy = v2.dy - (v2.y - v.y) * d * v.m * G
end
end
end
end
function moveBodies()
for k,v in pairs(bodies) do
v.x = v.x + v.dx
v.y = v.y + v.dy
end
end