Gravity
Model was written in NetLogo 6.2.0
•
Viewed 122 times
•
Downloaded 13 times
•
Run 0 times
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Comments and Questions
Please start the discussion about this model!
(You'll first need to log in.)
Click to Run Model
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INITIAL DECLARATIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; breed [bending-arrows bending-arrow] breed [fixed-objects fixed-object] breed [moving-objects moving-object] globals [ max-value-for-colour min-value-for-colour current-random-seed ] patches-own [ bending-direction bending-magnitude directions-list magnitudes-list ] turtles-own [ mass ] moving-objects-own [ velocity ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAIN SETUP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup ; OBSERVER do-housekeeping ; This line should remain BEFORE 'random-seed this-random-seed' (see 'to do-housekeeping' for an explanation of why). random-seed this-random-seed ; See 'to-report this-random-seed' for an explanation of this passage. Also, this line should remain ; AFTER 'do-housekeeping' (see 'to do-housekeeping' for an explanation of why). generate-fixed-objects generate-moving-objects set-values-for-colour end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAIN GO PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to go ; OBSERVER update-space ask moving-objects [move] if (collisions?) [manage-collisions] tick end to update-space ; OBSERVER ; Patches, inteded as bits of space-time, are bended by the presence of mass. The curvature of each patch is the combined effect of the ; individual bendings that each mass imposes on the patch. These are framed as vectors with a direction and a magnitude: the former is ; expressed in NetLogo degrees, the latter is the result of 'to-report bending-propagation' (see note on that procedure for more detail). ; The patch's resulting curvature (also a vector with a direction and a magnitude) is calculated by 'to-report resulting-vector-components'. let origins patches with [any? turtles-here] let targets target-patches ; What agents are contained in 'target-patches' depends on the value of 'light-update?' in the Interface: ; if 'light-update?' is TRUE, 'target-patches' will only contain the patches where a moving object currently ; is (i.e. only those patches that will need to compute their bending for the purpose of calculating the ; motion of moving-objects); if 'light-update' is FALSE, all patches will be in 'target-patches'. ask targets [ set directions-list (list) set magnitudes-list (list) set bending-direction "none" set bending-magnitude 0 ] ; At the moment 'origins' (i.e. some patches) are the agents executing this step, because at the moment the possibility of multiple objects ; (i.e. turtles) on the same patch is not ruled out. If and when there will be the implementation of objects on the same patch merging, it ; will become more convenient to have objects execute this passage, with the introduction of a 'reach' turtles-own variable that won't have ; to be computed at every step but only once upon creation (and in the occasion the mass of the object changes, e.g. through collision). ask origins [ let mass-here (sum [mass] of turtles-here) let reach (reach-based-on-mass mass-here) let relevant-targets (other targets in-radius reach) ask relevant-targets [ set directions-list lput (towards myself) (directions-list) set magnitudes-list lput (bending-propagation mass-here) (magnitudes-list) ] ] ; See 'to-report resulting-vector-components' for a thorough explanation of the calculations involved. ask targets [ let sum-vector (resulting-vector-components directions-list magnitudes-list) set bending-direction (first sum-vector) set bending-magnitude (last sum-vector) ] end to move ; MOVING-OBJECTS let dir-list (list heading bending-direction) let mag-list (list velocity bending-magnitude) let sum-vector (resulting-vector-components dir-list mag-list) if (first sum-vector = "none") [ set velocity 0 stop ] set heading (first sum-vector) set velocity (last sum-vector) forward (velocity / 50) end to manage-collisions ; OBSERVER let bigger-one NOBODY let smaller-one NOBODY ask moving-objects [ if (not any? other moving-objects in-radius 1) [stop] let other-object min-one-of (other moving-objects in-radius 1) [distance myself] ifelse (mass >= [mass] of other-object) [set bigger-one self set smaller-one other-object] [set bigger-one other-object set smaller-one self] ask bigger-one [ let dir-list (list heading [heading] of smaller-one) let mag-list (list (velocity * mass) ([velocity] of smaller-one * [mass] of smaller-one)) ; Velocities are multiplied by masses because momentum is the relevant quantity here. let sum-vector (resulting-vector-components dir-list mag-list) set mass (mass + ([mass] of smaller-one * 1)) ; The reason why this mass calculation is performed at this point (i.e. in the middle of the flow set size size-based-on-mass ; of commands that manage the call of 'to-report resulting-vector-components' and the result it ; provides) is that the old mass is needed to calculate the momentum to be given as input to the ; 'to-report resulting-vector-components' procedure, while the new mass is needed to set the new ; velocity value based on its results (see comment to that line). set heading (first sum-vector) set velocity (last sum-vector) / mass ; The result is divided by mass because that part of results is not a velocity but a momentum (as the ; 'to-report resulting-vector-component' procedure has been given a list containing momenta instead of ; velocities). ask smaller-one [die] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UTILITIES AT SETUP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to do-housekeeping ; OBSERVER ; IMPORTANT: This procedure should NOT contain any relevant randomness. ; The reason is that, in 'to setup', the 'random-seed' command is executed after 'do-housekeeping' (otherwise ; the 'clear-all' command included in 'do-housekeeping' would clear the global variable that is set during the ; execution of 'to-report this-random-seed'; check the comment on 'to-report this-random-seed' for more detail ; on this). Given that 'do-housekeeping' has to be executed before 'random-seed' in 'to setup', it follows that ; any relevant randomness in this procedure would be out of the control of the random seed, undermining its ; usefulness. ; Note that, although asking agentsets involves some randomness (because agents in an agentset are invoked in ; random order), this can be considered not-relevant as long as always the same agents are invoked (which is, ; for example, guaranteed by invoking all agents of a type, e.g. not breeds) AND as long as what agents are ; asked to do cannot vary from iteration to iteration (for example: 'ask patches [set pcolor black]'; on the ; contrary, the command 'ask patches [set pcolor black + random 3]' introduces relevant randomness). clear-all reset-ticks resize-world -30 30 -30 30 set-patch-size 9.57 ask patches [ set pcolor spacetime-base-colour + spacetime-shade set directions-list (list) set magnitudes-list (list) set bending-direction "none" ] set-default-shape fixed-objects "circle 2" set-default-shape moving-objects "circle" set-default-shape bending-arrows "arrow" end to generate-fixed-objects ; OBSERVER if (initial-number-fixed-objects > 0) [ create-fixed-objects 1 [ set mass (random 20) + 10 ; 8 8 set size size-based-on-mass set color fixed-objects-base-colour + objects-shade ] create-fixed-objects (initial-number-fixed-objects - 1) [ move-to one-of patches with [not any? fixed-objects-here] set mass (random 8) + 8 set size size-based-on-mass set color fixed-objects-base-colour + objects-shade ] ] end to generate-moving-objects ; OBSERVER create-moving-objects initial-number-moving-objects [ move-to min-one-of patches [bending-magnitude] set mass (random 4) + 2 set velocity (random-float 4) + 0.01 set size size-based-on-mass set color moving-objects-base-colour + objects-shade ] end to set-values-for-colour ; OBSERVER ; This procedure sets the values of 'bending-magnitude' to be used as maximum and minimum ; values for the range in 'scale-color' (for when the view needs to be updated with arrows ; representing the direction and magnitude of the bending). ; The reason for asking these two patches to set the value of 'max-value-for-colour' is because the ; intention is to have 'max-value-for-colour' (which will determine the colouring of arrows based ; on the bending magnitude of each patch) equal to the bending magnitude that the most massive ; object would exert on the closest patch. The bending magnitude of such scenario can be obtained ; by using 'to-report bending-propagation', which is a reporting procedure built to be executed ; by an agent being asked by another agent (that is because it uses 'distance myself'). Hence, the ; need to ask two agents to set this variable; specifically, 'patch 0 0' and 'patch 0 1' have a ; distance of 1 between themselves (which is what mimics the bending magnitude that the most massive ; object would exert "on the closest patch"; while 'max [mass] of turtles' is what mimics "the most ; massive object"). ; Note that this might need to change if and when it will be implemented a mechanisms (such as some ; form of merging of objects that are on the same patch) that will make it possible to be turtles ; (via 'mass'), and not patches (via 'sum [mass] of turtles-here'), invoking the 'to-report bending-propagation' ; procedure. In that case, in fact, the minimum distance between the involved agents will not be ; 1 anymore (i.e. the distance between the centers of two consecutive patches) but it will be less: ; something around 0.5 (i.e. the distance between a turtle standing close to the middle of one of ; its patch's border and the center of the closest patch). ask patch 0 0 [ ask patch 0 1 [ set max-value-for-colour (bending-propagation max [mass] of turtles) set min-value-for-colour (bending-propagation min [mass] of turtles) * 0.10 ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; COMMUNICATION WITH INTERFACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to base-view ; OBSERVER ask bending-arrows [ die ] end to bending-view ; OBSERVER let have-to-switch? FALSE if (light-update?) [ set light-update? FALSE set have-to-switch? TRUE ] update-space if (have-to-switch?) [ set light-update? TRUE ] ask patches with [bending-direction != "none"] [ sprout-bending-arrows 1 [ set heading bending-direction set color compute-colour ] ] if (fill-arrows-view?) [ ask patches with [bending-direction = "none"] [ sprout-bending-arrows 1 [ set heading ([heading] of min-one-of (bending-arrows with [bending-direction != "none"]) [distance myself]) set color black ;filling-arrows-colour + 2 ] ] ] ask bending-arrows [ set size 0.82 ] end to save-this-random-seed ; OBSERVER set random-seed-by-user current-random-seed end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TO-REPORT PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to-report this-random-seed ; A switch in the Interface lets the user select whether they want to provide a specific random-seed and, in case, an ; input box lets the user define it. Otherwise, a new random-seed is generated automatically with 'new-seed'. ; In both cases, the seed that is actually used is stored in the global variable 'current-random-seed', which is also ; showed in the Interface (to be precise, the value is first stored in the global variable and then, from there, it is ; reported to be used as seed). ifelse (select-random-seed?) [set current-random-seed random-seed-by-user report current-random-seed] [set current-random-seed new-seed report current-random-seed] end to-report size-based-on-mass report mass / 5 end to-report target-patches ifelse (light-update?) [report patches with [any? moving-objects-here]] [report patches] end to-report reach-based-on-mass [mass-here] let max-ignored-bending 0.0001 ; This is the maximum level of bending magnitude to be ignored (i.e. as if ; assumed to be small enough to be irrelevant). report mass-here * propagation-constant / max-ignored-bending end to-report bending-propagation [mass-here] ; The magnitude of bending is directly proportional to mass and inversely proportion to distance, therefore ; it is written here as 'B = (m / d) * k' where 'k' is the 'propagation-constant' set in the Interface. report (mass-here / (distance myself)) * propagation-constant end to-report resulting-vector-components [dir-list mag-list] ; This reporting procedure performs the sum of vectors. It takes two lists as inputs, that together ; determine the vectors acting on a specific agent: 'dir-list' contains NetLogo degrees indicating ; the directions in which said vectors operate; 'mag-list' contains their magnitudes. The procedure ; reports one list of two items: the first being the direction of the vector resulting from the sum ; of the original vectors; the second being its magnitude. ; This procedure is used both by patches and by objects: patches use it to determine the direction ; and magnitude of their bending (with the inputs being the vectors exerted by nearby objects); ; objects use it to determine the new direction and magnitude of their movement (with the inputs ; being the vector of their own last movement and the vector of their present patch's bending, or ; alternatively the vector of their own last movement and the one of the object they collide with). ; Directions expressed in NetLogo angles need to be converted to trigonometric angles, as ; this will allow the use of the 'cos' and 'sin' functions. let angles-list (list) foreach dir-list [ d -> set angles-list lput (heading-to-angle d) (angles-list) ] ; The directions and magnitudes of vectors are transformed into the coordinates of the vectors' ; head. This is done by applying 'cos' and 'sin' to the vectors' directions and multiplying them ; by their lengths. let vectors-x (list) let vectors-y (list) (foreach angles-list mag-list [ [a m] -> set vectors-x lput ((cos a) * m) (vectors-x) set vectors-y lput ((sin a) * m) (vectors-y) ]) if (not empty? vectors-x) [ let resulting-x (sum vectors-x) let resulting-y (sum vectors-y) if (resulting-x = 0) AND (resulting-y = 0) [report (list "none" 0)] let bending-dir (atan resulting-x resulting-y) let bending-mag (length-of-resulting-vector resulting-x resulting-y) report (list bending-dir bending-mag) ] end to-report heading-to-angle [h] ; This, used in 'to-report resulting-vector-components', is the formula for converting NetLogo headings (i.e. 0 = N, 90 = E etc) ; to trigonometric degrees (i.e. 0 = E, 90 = N etc). This is necessary in order to apply the 'sin' and 'cos' commands (that use ; trigonometric degrees) to 'directions-list' (that stores the directions from the patch to turtles in NetLogo degrees). This is ; done by converting the latter to 'angles-list'. report (90 - h) mod 360 end to-report length-of-resulting-vector [xx yy] ; This reporting procedure is used to compute the magnitude of patches' bending, with the patch being the point (0;0) ; and the other point (i.e. 'resulting-x' and 'resulting-y') being the head of the vector resulting from the sum of ; all the vectors acting on the patch. ; There are two options. Given that using 'report' immediately exits the procedure, the second option will never be ; used (even if it is not commented) unless the first option is commented. ; One option to perform this is to use the formula for the distance between two points in a Cartesian space, with ; one of the points being (0;0): report ((xx ^ 2) + (yy ^ 2)) ^ (1 / 2) ; The other option is to use 'distancexy'. Given that such command computes the distance between the agent executing ; the command and the coordinates given as arguments, it would require asking 'patch 0 0' to perform the calculation: let result 0 ask patch 0 0 [set result distancexy xx yy] report result end to-report compute-colour report scale-color arrows-base-colour bending-magnitude min-value-for-colour max-value-for-colour end
There is only one version of this model, created over 3 years ago by Matteo Sposato.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Gravity.png | preview | Preview for 'Gravity' | over 3 years ago, by Matteo Sposato | Download |
This model does not have any ancestors.
This model does not have any descendants.