packages feed

spade-0.2.0.0: samples/gravity.spd

graphics(true)
let ws = getwindowsize()
let sunx = (ws.width / 2 + 0)
let zoom = 1
let suny = (ws.height / 2)
let sun_radius = 50
let sun_velocity = [0, 0]
let planet_locations = [[100, 400, 0, 0], [130, 400, 0, 0], [150, 400, 0, 0]]
let planet_velocities = [[3.5, -2.9], [3.8, -2.9], [3.9, -2.9]]
-- let planet_velocities = [[0,0 ], [0, 0], [0, 0]]

let forces_on_sun = [[0, 0], [0, 0], [0, 0]]
let net_force_on_sun = [0.0, 0.0]
let paused = false
let lastpause = 0
let planet_mass = 6000
let sun_mass = 50689500
let vec_magnification = 0.1
let gs = getkeystate()
let time_inc = 0.01
loop
  clearscreen()
  draw_sun_at(sunx, suny)
  draw_planets(planet_locations)
  if not(paused) then
    let net_force_on_sun = [0.0, 0.0]
    for i = 1 to size(planet_locations)
      let planet_locations[i][1] = (planet_locations[i][1] + planet_velocities[i][1]*time_inc)
      let planet_locations[i][2] = (planet_locations[i][2] + planet_velocities[i][2]*time_inc)
      let sunx = (sunx + sun_velocity[1]*time_inc)
      let suny = (suny + sun_velocity[2]*time_inc)
      let accelerating_force_vector = compute_gravity_vector([sunx, suny], planet_locations[i])
      let forces_on_sun[i] = [-accelerating_force_vector[1], -accelerating_force_vector[2]]
      let net_force_on_sun = [(net_force_on_sun[1] + forces_on_sun[i][1]), (net_force_on_sun[2] + forces_on_sun[i][2])]
      let acceleration_x = (accelerating_force_vector[1] / planet_mass)
      let acceleration_y = (accelerating_force_vector[2] / planet_mass)
      let planet_locations[i][3] = accelerating_force_vector[1]
      let planet_locations[i][4] = accelerating_force_vector[2]
      let planet_velocities[i][1] = (planet_velocities[i][1] + acceleration_x*time_inc)
      let planet_velocities[i][2] = (planet_velocities[i][2] + acceleration_y*time_inc)
    endfor
    let sun_velocity = [(sun_velocity[1] + (net_force_on_sun[1] / sun_mass)), (sun_velocity[2] + (net_force_on_sun[2] / sun_mass))]
  endif
  -- handle keyboard input
  if inkeystate(gs, scancodes.q) then
    break
  elseif inkeystate(gs, scancodes.left) then
    let sun_velocity[1] = (sun_velocity[1] - 0.0001)
  elseif inkeystate(gs, scancodes.right) then
    let sun_velocity[1] = (sun_velocity[1] + 0.0001)
  elseif inkeystate(gs, scancodes.up) then
    let sun_velocity[2] = (sun_velocity[2] - 0.0001)
  elseif inkeystate(gs, scancodes.down) then
    let sun_velocity[2] = (sun_velocity[2] + 0.0001)
  elseif inkeystate(gs, scancodes.z) then
    let zoom = zoom + 0.001
    println(zoom)
    setlogicalsize((ws.width * zoom), (ws.height * zoom))
  elseif inkeystate(gs, scancodes.o) then
    setlogicalsize(ws.width, ws.height)
  elseif inkeystate(gs, scancodes.p) then
    let paused = not(paused)
    let lastpause = timestamp()
  endif
  let gs = getkeystate()
  render()
endloop
waitforkey()

proc compute_gravity_vector(sun_loc, planet_loc)
  let x_delta = (sun_loc[1] - planet_loc[1])
  let y_delta = (sun_loc[2] - planet_loc[2])
  let distance_sqr = (pow(x_delta, 2) + pow(y_delta, 2))
  if (distance_sqr < 300) then
    return [0, 0]
  endif

  let force = ((0.001 * (sun_mass * planet_mass)) / distance_sqr)
  let distance = pow(distance_sqr, 0.5)

  return [(force * (x_delta / distance)), (force * (y_delta / distance))]
endproc

proc draw_sun_at(x, y)
  circle(x, y, sun_radius)
  setcolor(50, 250, 250)
  foreach forces_on_sun as planet_force 
    arrow(x, y, (x + (vec_magnification * planet_force[1])), (y + (vec_magnification * planet_force[2])), 5, 5)
  endforeach
  setcolor(255, 0, 250)
  arrow(x, y, (x + (vec_magnification * net_force_on_sun[1])), (y + (vec_magnification * net_force_on_sun[2])), 5, 5)
endproc

proc draw_planets(planets)
  setcolor(255, 255, 255)
  foreach planets as p 
    circle(p[1], p[2], 10)
    setcolor(255, 0, 0)
    arrow(p[1], p[2], (p[1] + (vec_magnification * p[3])), (p[2] + (vec_magnification * p[4])), 5, 5)
    setcolor(0, 250, 0)
    arrow(p[1], p[2], (p[1] + (vec_magnification * p[3])), p[2], 5, 5)
    arrow(p[1], p[2], p[1], (p[2] + (vec_magnification * p[4])), 5, 5)
    setcolor(255, 255, 255)
  endforeach
endproc