defmodule Orbit do use VElixir.GenServer def start_link(opts \\ []) do GenServer.start_link(__MODULE__, nil, opts) end # def g, do: 6.67408e-11 def init(_) do {:ok, _} = VElixir.start_link state = %{ objects: Enum.map(1..300, fn _ -> %{vtype: Sphere, pos: V.random(0.2), radius: 0.05, color: Color.random, mass: 5, vel: V.random(1), orbit_point: V.random(0.2)} end), dt: 0, t: 0, render: [:objects] } {:ok, state} end def handle_cast({:update, dt, t}, state) do state = %{state|dt: dt, t: t} objects = state.objects |> VElixir.Misc.worker_map(10, fn obj -> update(obj, state) end) {:noreply, %{state|objects: objects}}#, arrow: Map.put(state.arrow, :dir, hd(objects).pos)}} end def update(obj, state) do obj |> calc_force |> calc_kinematics(state.dt) end def calc_force(obj) do r = obj.orbit_point - obj.pos force = norm(r) * obj.mass / :math.pow(mag(r), 1) Map.put(obj, :net_force, force) end def calc_kinematics(obj, dt) do accel = obj.net_force / obj.mass obj |> Map.put(:vel, obj.vel + accel*dt) |> Map.put(:pos, obj.pos + obj.vel*dt) end end