Packages

VElixir is a simple to use primitive 3D graphics library. It offers great performance, and ease of use. VElixir was inspired by VPython, which makes basic 3D graphics in python trivial. Now it's just as easy to make 3D graphical visualizations in Elixir.

Current section

Files

Jump to
velixir lib grav.ex
Raw

lib/grav.ex

defmodule Grav 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..100, fn _ ->
%{vtype: Sphere, pos: V.random(0.85), radius: 0.05, color: Color.random, mass: 5, vel: V.new}
end),
# arrow: %{vtype: Arrow, pos: V.new},
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(state.objects)
|> calc_kinematics(state.dt)
end
def calc_force(obj, objects) do
Map.put(obj, :net_force, Enum.reduce(objects, V.new, fn other_obj, net_force ->
if obj == other_obj do
net_force #make sure not to count force from ourselves
else
r = other_obj.pos - obj.pos
net_force + (norm(r) * ((1/length(objects)) * obj.mass * other_obj.mass / :math.pow(mag(r), 1)))
end
end))
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