Skip to content

Instantly share code, notes, and snippets.

@wybo
Last active May 1, 2017 23:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wybo/78e4557ef610be9abf04 to your computer and use it in GitHub Desktop.
Save wybo/78e4557ef610be9abf04 to your computer and use it in GitHub Desktop.
N-body
# AgentBase is Free Software, available under GPL v3 or any later version.
# Original AgentScript code @ 2013, 2014 Owen Densmore and RedfishGroup LLC.
# AgentBase (c) 2014, Wybo Wiersma.
# N body is a simulation of the nonlinear gravitation of n bodies.
u = ABM.util
class ABM.NBodyModel extends ABM.Model
setup: ->
@refreshPatches = false # for static patches
# globals
@population = 4
@sun = true
@v0max = 1
@gravExp = -2
# defaults
@agents.setDefault "shape", "circle"
@agents.setDefault "heading", 0 # override promotion to random angle
for patch in @patches.create().sample(@population)
patch.sprout 1, @agents, (agent) =>
if @sun and agent.id is 0
agent.mass = 10000
agent.moveTo x: 0, y: 0
agent.vx = agent.vy = 0
else
agent.mass = 10 + u.randomInt(1000)
agent.vx = @v0max * (1 - u.randomFloat(2))
agent.vy = @v0max * (1 - u.randomFloat(2))
# a.penDown = true
agent.size = 3 * u.log10(agent.mass)
# @agents.setDefaultPen(1, true)
@agents.setDefault "penSize", 1 #Pen(1, true)
@agents.setDefault "penDown", true #Pen(1, true)
step: ->
for agent in @agents
for agent1 in @agents.other(agent)
k = Math.pow(10, @gravExp) * agent1.mass /
Math.max(Math.pow(agent.distance(agent1.position), 3), .000001)
agent.vx += (agent1.position.x - agent.position.x) * k
agent.vy += (agent1.position.y - agent.position.y) * k
for agent in @agents when not (@sun and agent.id is 0)
# unless (@sun and a.id is 0)
agent.moveTo(
x: u.clamp(agent.position.x + agent.vx,
@patches.min.x, @patches.max.x),
y: u.clamp(agent.position.y + agent.vy,
@patches.min.y, @patches.max.y))
if Math.abs(agent.position.x) is @patches.max.x
agent.vx = u.sign(-agent.position.x) * .001
if Math.abs(agent.y) is @patches.max.y
agent.vy = u.sign(-agent.position.y) * .001
null
window.model = new ABM.NBodyModel {
div: "world",
patchSize: 2,
min: {x: -120, y: -100},
max: {x: 120, y: 100}
}
window.model.start()
# Uses the AgentBase library (03-02-2017 release)
# https://github.com/wybo/agentbase/commit/3501302567c018da82601cd858be2ea6d0b9c74d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment