Gravity Wells

No preview image

1 collaborator

Default-person Michael Kushnir (Author)


(This model has yet to be categorized with any tags)
Child of model Gravitation
Model group MAM-2016 | Visible to everyone | Changeable by the author
Model was written in NetLogo 3D 6.0-M5 • Viewed 363 times • Downloaded 25 times • Run 0 times
Download the 'Gravity Wells' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


This model is part of the Gravitational Model Suite. This model specifically displays "gravity wells" a visual representation of gravitational fields. While the other models in the suite simulate gravity in 3d space, this model simulates in 2d space, and uses the z axis to display the magnitude of the gravitational field at every point in space.


Every particle has mass, position, and velocity. At every time step, every particle pulls on every other particle with a gravitational force proportional to its mass and inversely proportional to the distance between the two particles. Each particle sums up these forces to calculate its total acceleration at every tick, and updates its velocity accordingly.

Uniquely to this model, the magnitude of the gravitational field is also calculated at every point in space, and displayed as the distance the mesh plane is distorted along the z-axis. This provides an intuitive view of the gravity of an object - the deeper of a distortion it makes, the stronger its pull, and being captured by its gravity is analogous to falling down its gravity well.


The NUMBER-OF-OBJECTS slider determines how many particles are spawned. The STARTING-BOX slider defines the coordinates they can be spawned inside - a smaller value spawns them closer to the center. MAX-STARTING-VELOCITY allows them to have a randomly determined starting velocity, and MAX-STARTING-MASS defines a maximum mass for the particles to be randomly assigned. SETUP sets up the model, and GO starts or pauses it. G and SoI are for display purposes only - G simply scales the amount that the mesh field is distorted, so higher values of G result in deeper gravity wells. SoI (or "Sphere of Influence") is the distance that a particle will affect visual updates for the gravity wells, so turning down SoI makes the model run faster, but loses visual accuracy farther away from the particles. Note that SoI DOES NOT affect physics calculations at all, only the visual gravity well display. ZOOM-FACTOR simply displays the amount that the model is zoomed in or out.


Notice that along an orbit, kinetic energy and potential energy are in opposition. When a particle reaches the highest point in its orbit (i.e., has the most potential energy), it is moving the slowest. When the particle reaches its lowest point, it is moving fastest. Conservation of energy states that a particle's total energy (kinetic + potential) must be constant unless it gains or loses energy by interaction with something else. Therefore, as it is moving through its orbit, it converts kinetic energy to potential energy and vice versa.

This also means that if (for example) a particle gains kinetic energy at the lowest point of its orbit, its highest point will correspondingly have more potential energy, which requires it to be farther away. In simpler terms, speeding up widens the opposite end of the orbit, and slowing down brings the opposite end closer. These are all emergent properties that result naturally from Newtonian laws of gravitation.


Try messing with G and SoI to make the gravity wells more apparent and visually interesting. Also try letting particles come near each other and seeing how their gravitational fields interact.


One of the biggest problems with this model is the simple fact that updating the mesh to display gravity wells is very computationally expensive and takes a long time. There are a bunch of ways that this could be made more efficient - the "sphere of influence" simplification is a pretty naive and simple one. It would also be possible to group together masses that are far away and treat them as one - this would simplify calculations a bit without completely disregarding things beyond an arbitrary distance. Or instead of doing calculations for every single point on the mesh, maybe a subset could be picked and the other point positions could just be extrapolated from there. However, while speeding this up would be great, I decided that accuracy is the #1 priority. This is a model, not a video game.


One workaround that was used was "zooming" in and out to compensate for the fact that Netlogo doesn't support resizing the world. So when a particle tries to go outside the bounds of the world, rather than making the world bigger, I just scaled down all the positions. This is why every turtle has a separate x-pos, y-pos and z-pos defined in addition to the default xcor, ycor and zcor; the new -pos variables are not scaled down and are used in all physics calculations, while the default cor variables are modified by the global zoom-factor variable and are used for displaying turtles. As a result, the world can effectively become bigger and smaller as needed.


This model is part of a suite of models, along with the Basic Gravitation model and the Orbital Playground model. The code for the gravity well mesh was also heavily inspired by the code from the Hill Climbing Example 3D model in the Models Library.


Wilensky, U. (1999). NetLogo [computer software]. Evanston, IL: Center for Connected Learning and Computer-Based Modeling, Northwestern University. .

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

globals [ zoom-factor ] ;; used to "zoom" by scaling the displayed positions of particles
breed [ stayers stayer ] ;; used as points to form the mesh that displays the gravity wells
breed [ particles particle ] ;; particles that interact and exert gravitational forces upon each other
turtles-own [
  x-pos y-pos z-pos ;; used as the basis for physics calculations - xcor, ycor, zcor only used for display
stayers-own [
  gravity ;; the magnitude of the total gravitational field at a given point
particles-own [
  x-velocity y-velocity ;; components of 2d velocity, used for physics calculations
  mass ;; also used for physics; the greater the mass, the greater the gravitational pull

to setup

  ;; create stayers
  ask patches with [pzcor = 0] [
    sprout-stayers 1
      set gravity 0
      create-links-with turtles-on neighbors
      set x-pos xcor
      set y-pos ycor

  set-default-shape turtles "circle"
  set zoom-factor 1
  create-particles number-of-objects [
    setxyz (random-float starting-box - random-float starting-box) (random-float starting-box - random-float starting-box) 0
    set x-velocity ((random-float max-starting-velocity) - (random-float max-starting-velocity))
    set y-velocity ((random-float max-starting-velocity) - (random-float max-starting-velocity))
    ;set z-velocity ((random-float max-starting-velocity) - (random-float max-starting-velocity))
    set mass random-float max-starting-mass
    set size mass ^ (1 / 3)
    set x-pos xcor
    set y-pos ycor
    set z-pos zcor

to go

to tick-once

;; Update positions of stayers to correspond with gravitational field

to compute-gravity-wells

  ask stayers [ set gravity 0
    set x-pos xcor * zoom-factor
    set y-pos ycor * zoom-factor
  ask particles [
    ask stayers with [distancexy [xcor] of myself [ycor] of myself < SoI] [
      let xdist [x-pos] of self - [x-pos] of myself
      let ydist [y-pos] of self - [y-pos] of myself
      let scale-const max list ((xdist ^ 2 + ydist ^ 2) ^ .5) ([size] of myself / 2)

      set gravity gravity + [mass] of myself * G / scale-const
  ask stayers [
    set z-pos gravity * -1
    set zcor z-pos / zoom-factor
    ; set color scale-color red zcor 0 -50

to set-particle-display-positions
  ask particles [
    set z-pos [z-pos] of min-one-of stayers [distancexy [xcor] of myself [ycor] of myself]
    set zcor z-pos / zoom-factor

    if not hidden? [
      set xcor x-pos / zoom-factor
      set ycor y-pos / zoom-factor
      set size mass ^ (1 / 3) / zoom-factor

;; Check center of mass of the overall system, adjust view accordingly

to check-slide
  let CoM center-of-mass particles
  slide-view (item 0 CoM) (item 1 CoM) (0)

;; Calculate the center of mass of the entire system

to-report center-of-mass [turtleset]
  ; R = 1/M sigma (mi * ri)
  let M 0
  let totalx 0
  let totaly 0
  ;let totalz 0
  ask turtleset [
    let mi [mass] of self
    set M M + mi
    set totalx totalx + [x-pos] of self * mi
    set totaly totaly + [y-pos] of self * mi
    ;set totalz totalz + [z-pos] of self * mi

  report (list (totalx / M) (totaly / M))

to check-boundaries
  let flag false
  ask particles [
    if abs (x-pos + x-velocity) > max-pxcor * zoom-factor * .8 or
    abs (y-pos + y-velocity) > max-pycor * zoom-factor * .8; or
    ;abs (z-pos + z-velocity) > max-pzcor * zoom-factor * .8
      set flag true

  ifelse flag [
    ;print "zooming out"
    set-zoom 1.1
    ;print "zooming in"
    set-zoom .9

  ask particles [
    ifelse abs (x-pos + x-velocity) > max-pxcor or abs (y-pos + y-velocity) > max-pycor or abs (z-pos) > max-pzcor
    [ set hidden? true ]
    [ set hidden? false ]

;; Have particles compute their acceleration based on gravitational interactions with all other particles

to compute-acceleration-changes
  ask particles [
    let turtle1 self
    ask other particles [
      gravitationally-affect turtle1 self

;; Move particles according to their velocity

to move-particles
  ask particles [
    set x-pos x-pos + x-velocity
    set y-pos y-pos + y-velocity
    ;set z-pos z-pos + z-velocity

;; Compute gravitational pull between a pair of particles

to gravitationally-affect [ affected affecting ]
  ; g = m1 * m2 / r^2
  ; r = sqrt(xdist^2 + ydist^2) -> r^2 = xdist^2 + ydist^2
  let xdist [x-pos] of affecting - [x-pos] of affected
  ;print xdist
  let ydist [y-pos] of affecting - [y-pos] of affected
  ;print ydist
  ;let zdist [z-pos] of affecting - [z-pos] of affected
  let total-acc 0
  let xyangle 90
  ;let zangle 90
  let xydist (xdist ^ 2 + ydist ^ 2) ^ .5
  if xdist + ydist > 0 [
    set total-acc [mass] of affecting / (xdist ^ 2 + ydist ^ 2)
    let angle-heading atan xdist ydist
    set xyangle (90 - angle-heading) mod 360
    ;set zangle (90 - z-angle-heading) mod 360

  if total-acc > 50 [ set total-acc 50 ]

  set total-acc total-acc / 20
  ;let xyacc total-acc * (cos zangle)

  ask affected [
    set x-velocity (x-velocity + total-acc * (cos xyangle))
    set y-velocity (y-velocity + total-acc * (sin xyangle))
    ;set z-velocity (z-velocity + total-acc * (sin zangle))

;; Move view laterally

to slide-view [deltax deltay deltaz]
  ask particles [
    set x-pos x-pos - deltax
    set y-pos y-pos - deltay
    set z-pos z-pos - deltaz

;; Change zoom-factor to zoom in or out

to set-zoom [new-zoom]
  set zoom-factor zoom-factor * new-zoom

There are 3 versions of this model.

Uploaded by When Description Download
Michael Kushnir about 8 years ago Final modifications Download this version
Michael Kushnir about 8 years ago Final improvements Download this version
Michael Kushnir about 8 years ago Model of 2d space showing gravity wells in 3d Download this version

Attached files

No files

Parent: Gravitation

This model does not have any descendants.

Graph of models related to 'Gravity Wells'