Good morning:
I am currently working on a netlogo program where I have a file with the turtle coordinates and I need to import that file so each turtle adopts the position that it is in the file. The file is the following:
9.220967873876688 30.6518906113243
-11.68237910031844 -11.246301104888516
2.5642482677264593 -1.6456061198786152
24.89458409582633 22.473096145446608
33.714972669018216 -17.295603130774897
10.347090714821402 13.476191522153966
3.881957027308774 -18.70063134965679
-21.711570773095524 -25.038263308838506
-20.649763022691737 28.674828042635635
-5.107177490557619 21.26440747439797
-6.29157511915799 -32.595514274136164
19.134302620042213 -26.443694241313267
-27.207781014142487 -3.48941202705942
18.198639754306242 -9.202785605985115
-12.82510430838797 5.818222632445828
-28.761569626881588 13.521815467262908
34.93451881825029 -34.49959417879696
27.234341179357532 5.506201903765271
The first column is the x axis and the second column is the y axis. The world dimension is y axis (-35,35) and x axis (-35,35). In this example there are 20 coordinates. So I want to do an import from this file which generates 20 turtles placed according to the file coordinates.
Thank you for your help.
Assuming the coordinates file is a text file with values separated by spaces and carriage returns, as it seems from the question, the file-related primitives are enough.
There are two possible cases.
You know in advance how many turtles' coordinates there will be
In this case, just use file-open, file-read and file-close:
to setup
clear-all
file-open "coordinates.txt"
create-turtles 18 [
setxy file-read file-read
]
file-close
end
(note that your file example contains 18 pairs of coordinates, not 20)
You don't know in advance how many turtles' coordinates there will be
In this case, add a while loop using file-at-end?:
to setup
clear-all
file-open "coordinates.txt"
while [not file-at-end?] [
create-turtles 1 [
setxy file-read file-read
]
]
file-close
end
Related
I am new to Netlogo and learning a model is about animals moving around to eat grass based on the grazing model from NetLogo. The moving behavior is based on the biomass's richness, so it is not just impacting at right angles.
Given the conditions, I don't know how to add a monitor in my model that calculates the total distance a turtle moved by traveling each pixel.
Move specifically, I wonder if there is a way to calculate the total length of the pen-marked lines. (Show in the picture)
enter image description here
The basic setting of move is
to move-turtles
uphill-biomass
forward 1
set distance-traveled (distance-traveled + 1)
if not can-move? 1 [ rt random 150 ]
end
to uphill-biomass
let biomass-ahead biomass-scent-at-angle 0
let biomass-right biomass-scent-at-angle 35
let biomass-left biomass-scent-at-angle -35
if (biomass-right = biomass-ahead) and (biomass-left = biomass-ahead) [ wiggle ]
if (biomass-right > biomass-ahead) or (biomass-left > biomass-ahead)
[ ifelse biomass-right > biomass-left
[ rt 35 ]
[ lt 35 ] ]
end
Thank you very much for any helps!
You need to use some turtle variables with the turtles-own primitive and do the distance calculation by hand.
The easiest way to do such a calculation is to save the coordinates between a turtle's previous coordinates with turtle variables and then use the distancexy primitive (link for dictionary entry: https://ccl.northwestern.edu/netlogo/docs/dictionary.html#distancexy)
Here's a simple implementation:
turtles-own [last-x last-y distance-traveled]
move-turtle
uphill-biomass
set last-x xcor
set last-y ycor
forward 1
set distance-traveled (distance-traveled + (distancexy last-x last-y))
if not can-move? 1 [ rt random 150 ]
end
I hope this answers your question.
I want to change the mean, lambda, of a poisson process every time ticks advance by one.
Let's say lambda is a predetermined list of the following numbers: [1 2 3 4 5].
If I define lambda in this way, is it possible for NetLogo to loop through each position of the list based on the time step? E.g., at the first tick, NetLogo will set lambda to equal to the first item of the list, such that lambda = 1, when tick = 2, lambda = 2, etc.
Here is an example of what I'm trying to do:
to recruit-spores
ask turtles with [color = red] [
hatch-spores random-poisson lambda ; lambda is what I want to change at every tick
[set shape "dot"
set size 0.01
set color orange
setxy random-xcor random-ycor ]
]
end
Is there a way to change the value of lambda by looping through a list in NetLogo? Either through NetLogo's built-in functionality, or through an extension? Is there a way to do this using the R extension?
Straightforward to do it entirely in NetLogo if you want. The reproducible code below shows how you can use first, lput and but-first to take (in this example, print) the first value of the list and then append it to the end of the list:
globals [
lambda-values
]
to setup
set lambda-values [1 2 3 4 5]
end
to go
print first lambda-values
set lambda-values lput (first lambda-values) lambda-values
set lambda-values but-first lambda-values
tick
end
To put this in your example, it would be:
to recruit-spores
let current-lambda first lambda-values
set lambda-values lput current-lambda lambda-values
set lambda-values but-first lambda-values
ask turtles with [color = red] [
hatch-spores random-poisson current-lambda [
set shape "dot"
set size 0.01
set color orange
setxy random-xcor random-ycor
]
]
end
Alternatively, you can use remainder or mod, in combination with the current value of ticks, to find out the position of the item that needs to be extracted from the list (you can extract it using item). This solution might be in some way less preferable than the previous one, as it is ticks-dependant (as opposed to the previous one).
Another approach: implement a counter variable that is incremented each time that you use a value from lambda-values and that indicates the position of the next item you want to extract, and that is reset to 0 when it reaches the end of the list. This latest solution might be the least preferable because it requires you to create a global variable for the counter.
I am new to NetLogo, so my apologies in advance if that question is very stupid. I would like to create an Agent-Based Model where animals move around in a complex terrain looking for water sources. Movement should be downhill, constrained by steep slopes (>25°) and targets should be lakes. I am using a real-world example from GIS data for this, and I have already managed to setup a world containing an ASCII elevation grid, a shapefile containing lines that represent slopes steeper 25degrees and a shapefile containing areas representing lakes. I have created animals (cows) and found a code line telling them to move downhill. Now, I would like to tell them
a) to avoid slopes >25° by using the slope shapefiles as obstacles and
b) to go to the lakes by using the lake shapfiles as targets
Can someone help me how to code this?
Many thanks in advance!
Here is the code I have put together so far
breed [ cows cow ]
extensions [ gis ]
patches-own [ elevation ]
globals [
slope-dataset
lake-dataset
elevation-dataset
]
to setup-terrain
clear-all
reset-ticks
set slope-dataset gis:load-dataset "FILENAME.shp" ;;extent of GIS datasets is N42.3-43.4 and W120.0-121.1
set lake-dataset gis:load-dataset "FILENAME.shp"
set elevation-dataset gis:load-dataset "FILENAME.asc"
gis:set-world-envelope gis:envelope-of slope-dataset
gis:set-world-envelope gis:envelope-of lake-dataset
gis:set-world-envelope gis:envelope-of elevation-dataset
end
to display-slopes
gis:set-drawing-color red
gis:draw slope-dataset 0.5
end
to display-lakes
gis:set-drawing-color blue
gis:draw lake-dataset 2
end
to display-elevation-in-patches
gis:apply-raster elevation-dataset elevation
let min-elevation gis:minimum-of elevation-dataset
let max-elevation gis:maximum-of elevation-dataset
ask patches
[ ; note the use of the "<= 0 or >= 0" technique to filter out
; "not a number" values, as discussed in the documentation.
if (elevation <= 0) or (elevation >= 0)
[ set pcolor scale-color black elevation min-elevation max-elevation ] ]
end
to setup-cows
set-default-shape cows "cow"
create-cows 100 [
setxy random-pxcor random-pycor
set size 1
set color white
]
end
to move
move-to patch-here ;; go to patch center
let p min-one-of neighbors [elevation]
if [elevation] of p < elevation [
face p
move-to p ;; makes cows move to the next lower elevation patch, if no lower
elevetion is present, cow doesn't move
]
end
to go
ask cows [
move
]
end
Thanks Seth, I have found the solution using the gis:intersects? primitive you suggested:
to display-slopes
ask patches gis:intersecting slope-dataset
[ set pcolor red ]
end
to go
ask cows
[fd 1
avoid-ostacles]
tick
end
to avoid-obstacles
ask cows [
if [pcolor] of patch-ahead 1 = red
[rt 90 fd 1]]
end
This way I can color the patches in red that intersect with the shapefile containing the slope vector dataset and then ask the cows to avoid and move around red colored patches.
Thanks again!
I have sorted all the turtles by the value of a property called point.
now I want a plot of point versus turtle number. how do I do this?
turtles-own [ point ]
to setup
ca
crt 100
reset-ticks
end
to go
repeat 100[
ask turtles[
if random 10 = 1[
set point point + 1
]
]
];;sorting
let array sort-on [point] turtles
tick
end
By "turtle number", I assume you mean the location in the list. Then replace let array sort-on [point] turtles with plotByOrder where
to plotByOrder
clear-plot
let pts sort [point] of turtles
foreach pts [[pt] -> plot pt]
end
Of course, you will need to have created a plot in the interface, and this assumes it is the current plot.
Is it possible to create random shapes (see below for example) of a given area in NetLogo?
A first stab at Seth's suggestion #1. It creates a neat visual too!
patches-own [ height ]
to blobbify
clear-all
repeat (ceiling 2 * (ln (world-height * world-width))) [
ask patch (round (random (world-width / 2)) - world-width / 4)
(round (random (world-height / 2)) - world-height / 4)
[ set height world-width * world-height ] ]
while [ count patches with [ height > 1 ] < (world-width * world-height / 4)]
[ diffuse height 1
ask patches with [ height > 0 ] [ set pcolor height ]
]
ask patches with [ height > 1 ] [ set pcolor white ]
end
I found a really simple approach that produces pretty nice results.
Create a turtle. The turtle performs a random walk. After each step, they set the uncolored patch closest to them to the desired color. The turtle does this a number of times equal to the desired area.
Here's the code:
to make-blob [ area ]
let blob-maker nobody
crt 1 [ set blob-maker self ]
repeat area [
ask blob-maker [
ask min-one-of patches with [ pcolor = black ] [ distance myself ] [ set pcolor blue ]
rt random 360
fd 1
]
]
ask blob-maker [ die ]
end
This naturally produces nicely curved blobs.
Making the turtle's step size smaller makes the blob more circle-y. Making it bigger results in thinner, more sporadic blobs (though you run the risk of getting disconnected patches).
Edit:
I noticed that my answer runs quite slowly when you have a gigantic number of patches. Here's a much faster version:
to make-blob [ area x y ]
let blob-maker nobody
crt 1 [ set blob-maker self setxy x y ]
let border patch-set [ patch-here ] of blob-maker
repeat area [
ask blob-maker [
ask min-one-of border [ distance myself ] [
set pcolor green
set border (patch-set border neighbors4) with [ pcolor = black ]
]
rt random 360
fd .8
]
]
ask blob-maker [ die ]
end
Generating random blobs is a hard problem with no obvious solution. Fixing the area of the blob makes it even harder.
You'll need to pick an approach, then try to figure out how to express that approach in NetLogo code.
As for what approach to pick, I imagine there's literature on this if you search. But just off the top of my head, I have three ideas:
Scatter random points around the world, use diffuse to make a smooth landscape around these peaks. (See the Diffusion Graphics model, in the Art section of NetLogo's Models Library, for code for this; you'll want to turn world wrapping off, though.) Then select only those patches where the "elevation" exceeds some threshold. To get the desired area, vary the threshold until the target is reached.
Draw a curve around the center point using polar coordinates, where theta goes from 0 to 360 and 4 varies randomly. You'll need a way to get smooth random variation in the radius, perhaps by generating random numbers and then applying a smoothing function to them. In order to force the blob to have the desired area, first generate the whole curve, then scale it as needed. You'll need some trick to avoid a discontinuity where theta = 0, perhaps by using a smoothing function that wraps.
Generate a random polygon by scattering points around the world, then discarding some or all points in the middle. (You could take the convex hull, but then you'll always get a convex shape, which might not be "blobby" enough for you. So you might want to something like like generating n random points and then keeping the m points that are farthest from the center, without regard to convexity.) Once you've got the random polygon, apply some smoothing function to turn it into a curvy blob. Then scale the whole thing as necessary to get the desired area.