How can I separate left- and right-vision field of a turtle in NetLogo? - netlogo

I want to separate left- and right-vision fields of a turtle in NetLogo.
Left-vision field means angles are -179 to -1 degrees while right-vision field means angles are from 1 to 179 if an angle of front of a turtle is 0 degrees.
In NetLogo, patch-right-and-ahead and patch-left-and-ahead can separate left- and right-vision fields of a turtles, but those codes is only a angle incorporate a turtle.
And, in-cone can not separate the vision fields.
Is there any codes to program this in NetLogo?

You can save the turtle's current heading, turn it 90-degrees left and see what's on the left side of the original heading with
scan x 180
then turn it 90-degrees right from original heading and see what's on the right side of the original heading with
scan x 180
then turn it back to its original heading.
Here's code that illustrates this. Set the scan angle to something smaller than 180 to see more clearly what's happening. As you step through the go step it rotates and highlights what it is seeing.
globals [ scan-angle]
turtles-own [ actual-heading ]
to setup
clear-all
set scan-angle 180
create-turtles 1 [ set size 4 set heading 0 set actual-heading heading]
reset-ticks
end
to go
ask turtle 0 [ set heading (heading + 30) set actual-heading heading]
scansides scan-angle
tick
end
to scansides [ angle ]
ask patches [ set pcolor black]
ask turtle 0
[
;; scan left side
set heading (actual-heading - 90)
ask patches in-cone 10 angle [ set pcolor red]
;; scan right side
set heading (actual-heading + 90)
ask patches in-cone 10 angle [ set pcolor green]
set heading actual-heading
]
end

Related

Netlogo: measure mean distance between start and end patches

I am teaching myself how to create ABMs in Netlogo using the book of Railsback & Grimm 2012. I am having trouble with one book exercise which is on butterflies following "virtual" corridors. Basic idea is that butterflies go uphill for mating using the differences in height as guide. I need to calculate the width of the corridors dividing the number of patches used by the butterflies over the average distance the butterflies fly from the start patch to the end patch. I am
struggling with plotting this corridor width, which I am coding like this:
to-report corridor-width
let patches-visited count patches with [used?]
let mean-distance mean [distance start-patch] of turtles
report patches-visited / mean-distance
I then created a plot in the interface with the command:
plot corridor-width
The error message I get reads:
Division by zero. error while observer running / called by procedure
CORRIDOR-WIDTH called by plot 'Corridor width' pen 'default' update
code called by procedure SETUP called by Button 'setup'
I believe there is something wrong with the way I am coding distance start-patch but I have surfed the web and looked at several codes and I cannot spot my mistake. My whole code looks like this:
globals [ q ] ;; q is the probability that butterfly moves directly to highest patch
turtles-own [ start-patch ]
patches-own [ elevation used? ] ;; patches property of elevation and whether the patch has been used by butterfly or not.
to setup
ca
;; Let's create patches and asign them an elevation and color by using ask patches statement
ask patches
[
;; Elevation decreases linearly with distance from the center of hills. Hills are at (30,30) and
;; (120,120) coordinates. The first hill is 100 units high whereas the second one is 50
let elev1 100 - distancexy 30 30
let elev2 50 - distancexy 120 100
ifelse elev1 > elev2
[ set elevation elev1 ]
[ set elevation elev2 ]
set pcolor scale-color green elevation 0 100
set used? false
]
;; Create 50 butterflies
crt 50
ask turtles [
set size 6
;; set their initial location as their initial patch
setxy random-pxcor random-pycor
set start-patch patch-here
;; have the butterfly draw its path with the pen-down statement
pen-down
]
reset-ticks
;; Initialize the q parameter
set q 0.4
end
;; The master schedule
to go
ask turtles [ move ]
plot corridor-width
tick
if ticks >= 1000
[
let final-corridor-width corridor-width
write "Corridor width: " print final-corridor-width
;export-plot "Corridor width" (word "Corridor-width-output-for-q-" q ".csv")
stop
]
end
;; let's code the butterfly procedure of movement
to move
if elevation >=
[ elevation ] of max-one-of neighbors [ elevation ]
[ stop ]
ifelse random-float 1 < q ;; Decide whether to move to the highest sorrounding
;; patch with p=q
[ uphill elevation ] ;; move deterministically uphill
[ move-to one-of neighbors ] ;; or move randomly
set used? true
end
to-report corridor-width
let patches-visited count patches with [used?]
let mean-distance mean [distance start-patch] of turtles
report patches-visited / mean-distance
end
What happens when the mean-distance is 0?
let mean-distance mean [distance start-patch] of turtles
Essentially, in your setup, you set all the turtle's start-patch to their current patch. So, if you ask all the turtles how far away they are from their start patch, they will all tell you 0 units away.
So, [distance start-patch] of turtles is filled with a list of all 0's.
Thus, a mean of a list of all 0s is 0 causing your divide by 0 error.
Maybe in this situation, you want to report 0 instead...so
ifelse mean-distance = 0
[ report 0]
[report patches-visited / mean-distance]

NetLogo: identification of valleys = rivers location in artificial landscape

I want to produce the artificial landscape, containing hills, slopes and valleys. So far, so good. Now, I want to place a rivers in the bottom of the valley. I thought that the easiest way will be ask turtle to move uphill/downhill by elevation as drops here: http://modelingcommons.org/browse/one_model/2352#model_tabs_browse_info
However, as my landscape is not real, my valleys are also not linears, but just the "depressions" in the terrain, and thus my river localisation is really weird looking?
Please, is there a way to create hills and valleys reflecting the real terrain in netlogo without using GIS extension? I've found great models of Erosion, Watershed and GIS gradient example, but how can I initially place my turtles to stay only in valleys?
EDIT
the GIS gradient example provide excellent problem solving of movement of all the cells over the space, and they aggregate in valleys. However, as I want to by movement of my turtle "create" the river bed on the bottom of the valley, how can I place it? maybe start at the lowest point and stop after several ticks to not to allow to get on the top of the hill? thank you !
globals [
low
high
range ]
patches-own [
altitude ]
to setup
clear-all
setup-hills
scale-patches
color-patches
end
to setup-hills
ask n-of 2 patches [
set pcolor magenta ]
ask patches [
let max_dist sqrt (world-width ^ world-width + world-height ^ world-height)
set altitude world-width - distance patch 10 10
set altitude world-width - distance min-one-of patches with [pcolor = magenta][distance myself]
]
crt 1 [ ; create a turtle, needed to identify the lowest slope
set color red
let bottom_valley min-one-of patches [altitude]
move-to bottom_valley
]
end
to scale-patches
set low [altitude] of min-one-of patches [altitude]
set high [altitude] of max-one-of patches [altitude]
set range high - low
ask patches [
set altitude altitude - low ; shift every patch down so lowest altitude is 0
set altitude altitude * 99.0 / range ; scale every patch so that the lowest is 0 and highest is 999
]
repeat 5 [
diffuse altitude 0.5 ]
end
to color-patches
ask patches [
set pcolor scale-color green altitude 0 100]
end
to create-river
ask turtles [
let p max-one-of neighbors in-radius 1 [altitude]
if [altitude] of p >= altitude [
face p
move-to p
set pcolor blue
]
]
end
You have the right general idea. I recommend checking out the "GIS Gradient" model on your landscape. You can find it in the Models Library under Code Examples/GIS. Then think how to filter patches that have a minimum number of water particles passing through it over time.
Identification of system of rivers on the landscape using GIS Gradient Example:
http://modelingcommons.org/browse/one_model/2352#model_tabs_browse_info
The whole process of identification of the river system on the complex landscape is composed by 3 subprocesses:
identify the highest points of the landscape
place here the river source (create-source)
identify patches for a downhill stream
from the highest river source, by decreasing elevetion of neighboring cells to the lowest elevation of the river valley
when turtle reaches the edge of the world, turtle dies (go-downhill)
remove top hill points (as the river does not read the summit of the hill)
the river does not start at the top of the hill, but at the highest point of the valley
the highest "river" patches from the river beds system are removed (remove-river-from-top-hill)
The number of sources depends of type of GIS data you have available. The same for the number of patches you wish to remove from the top of the hill.
;; ----------------------------------------------
;; create river
;; ----------------------------------------------
to create-source
; identify the 5 highest points of the landscape
repeat 5 [
; avoid the highest points to be close to each other
ask max-one-of patches with [ not any? turtles-here and not any? turtles in-radius 20 ] [p_elev] [
;ask patches to sporout turtles
sprout 1 [
set size 1
set color orange
]
]
]
end
to go-downhill
; stop if there is no more turtles
if not any? turtles with [color = orange]
[ stop ]
; ask turtles located on top of thehills to move downhill
ask turtles with [color = orange] [
; die when you reach the edge of the world
if ([pxcor] of patch-here = max-pxcor) or ([pycor] of patch-here = max-pycor)
or ([pxcor] of patch-here = min-pxcor) or ([pycor] of patch-here = min-pycor) [
die ]
move-to patch-here ; go to patch center
set pcolor blue ; identify the use of patch
set p min-one-of neighbors with [pcolor != blue ] [p_elev] ;; or neighbors4 with [pcolor != blue]patches in-radius 3
if p != nobody [
; move downhill if elevation of patch you are standing on is higher then one of the neighboring patches
ifelse [p_elev] of p <= p_elev
[
face p
move-to p
set pcolor blue ; identify the use of patch
]
[
;move-to min-one-of patches with [pcolor != blue] [distance myself]
move-to min-one-of patches in-radius 2 with [pcolor != blue] [p_elev]
set pcolor blue ; identify the use of patch
]
]
]
end
to remove-river-from-top-hill
; remove 5% of the blue (river) patches placed on the top of the hill
let total_blue count patches with [pcolor = blue]
repeat total_blue * 0.05 [
ask max-one-of patches with [pcolor = blue] [p_elev] [
set pcolor yellow ]
]
end
Complex river system identified:
(river bed = BLUE, removed top of the hill = YELLOW):

unable to make non-stationary turtles change their direction if an obstacle a patch ahead

If any one please give some time.
I have an area(say a colony) with boundary wall as black patches and at some point within the boundary there is one building with building wall as blue patches. People(breed) are normally moving inside boundary and the building as well. Also they are entering and going out of the boundary. Due to some reason (suppose rumor) and after certain condition (if more than 15 person hears the rumor) they starts moving randomly with any of the headings 0, 90, 180 and 270. So, the problem I am unable is, to apply check on the turtles(people) randomly moving to change their heading or turn back if they sense the boundary or wall a patch ahead.
I tried following ways but not working, they simple passes form these patches
1) Asked the turtles if heard-rumor? and times-heard > 1 [
if [pcolor] of patch-ahead 1 = blue [set heading [heading] of self - 180]
if [pcolor] of patch-ahead 1 = black [set heading [heading] of self - 180] ]
2) set patches with boundary-wall [set pcolor black] and building-wall [set pcolor blue] and then set patch variables boundary-wall? And building-wall? true on these patches. Further asked the turtles
if heard-rumor? and times-heard > 1 [
if boundary-wall? or building-wall? [ set heading [heading] of self - 180 ] ]
The procedure sequence is
to go
ask people [ ;breed
fd speed
spread-rumor
people-wander ]
end
So after spread-rumor function,
to people-wander
if heard-rumor? and times-heard > 1 and inside-boundary?
[
if people-heard-rumor > 10 [ set heading one-of (list 0 90 180 270) ] ];random 360
;people-heard-rumor is a count how many have received rumor
if heard-rumor? or fear-worst? [
; if [pcolor] of patch-ahead 1 = blue [set heading [heading] of self - 180]]
; if [pcolor] of patch-ahead 1 = black [set heading [heading] of self - 180]]
boundary-wall? or temple-wall? [set i? true set heading [heading] of self - 180 show 5] ]
end
I don’t know what wrong I am doing. But surely I am not using proper way. Any help is deeply thankful.
You start out with fd speed so your people will go right through the barriers on that command without ever testing for a barrier. Note that even if you were to test 1 patch ahead before doing that, if speed can be greater than 1, you could still go right through the barriers. Furthermore, in a corner a person might have a barrier both in front of it and behind it, so reversing course can also be a problem.
Btw, [heading] of self is the same as heading, and to turn around it is more natural to say rt 180.
EDIT (in response to comment):
Here is a simple example of moving step by step, checking along the way:
to fd-with-checks [#speed]
repeat #speed [
ifelse (isbarrier? patch-ahead 1) [
stop
] [
fd 1
]
]
end
to-report isbarrier? [#patch]
report pcolor = blue or pcolor = black
end

Find the presence of other turtles in a given direction upto a distance

I wish to find out whether in a given turtle's heading there is another agent present upto a given distance.
Here the Distance is "D".
Note:
Any agent present before D in the given direction should be also considered.
Even the direction doesn't coincide with the other's agent centre but just touches it ,even then that agent should be considered.
Problem:
No turtle-ahead procedure available. Combination of patch-ahead and turtles-on not applicable due to patch-size>> turtle-size.
Possible approach:
1.Represent the turtle's heading by the equation of a line.
to-report calculate-line[x y angle]
let m tan angle
let A m
let B -1
let C (- m * x + y)
report (list A B C)
end
to-report heading-to-angle [ h ]
report (90 - h) mod 360
end
let line-equ calculate-line (xcor) (ycor) (heading-to-angle heading)
2.Calculate the perpendicular distance from other turtles here, Check if there are within a range that the size of other turtles.
to-report value[A X1 Y1];;A is list of coefficents of line, x1 and y1 are coordinates of red turtle
if-else(abs((item 0 A * X1 + item 1 A * Y1 + item 2 A) / (sqrt((item 0 A ^ 2) + (item 1 A ^ 2) ))) < [size] of wall )
[ report "true"][report "false"]
end
3.To check if the red turtle is within D. One could obtain a line perpendicular to black one and compute the red turtle distance from it to check if it is less than or equal to D. But then that adds more complication.(Though one can simplify rotate the turtle by 90 left or right and get the line equation.)
This is what I meant by my comment. Run this code (as its own model). What it does is turn all the turtles on a few 'ahead' patches a different colour. I know this is not what you are trying to do, but the agentset candidates is a relatively small number of turtles. These are the only ones that you have to check whether they are on the correct path. So instead of turning them a different colour you could check the direction that they are from your initial turtle.
to setup
clear-all
set-patch-size 25
resize-world -10 10 -10 10
create-turtles 1000
[ setxy random-xcor random-ycor
set color yellow
set size 0.4
]
ask one-of turtles
[ set color red
set size 1
check-from-me 5
]
end
to check-from-me [howfar]
let counter 0
let candidates turtles-here
while [counter < howfar]
[ set counter counter + 1
set candidates (turtle-set candidates turtles-on patch-ahead counter)
]
ask candidates [set color red]
end
to-report check-wall
let return false
hatch 1[
set color black
set size ([size] of one-of walls) / 2
show (2.5 * ([size] of myself))
while [distance myself < (2.5 * ([size] of myself))]
[
fd ([size] of one-of walls) / 64
if any? walls in-radius size
[
set return true
]
show distance myself
]
]
report return
end
The above works. But still is approx. I am looking for better solution with probably less maths as one elucidated in the question.

Trying to get factions to arrange in segments? NetLogo code advice

I've made a model that aranges factions (turtles in different colours) in a circle.
At the moment they arrange randomly, was wondering if someone could help me arrange them so, for example, red occupies the first 90 degrees, blue the next 90 degrees, etc (on setup).
Here's my code...
ask patch 0 0
[ ask patches in-radius ( max-pxcor * .9) with [ random-float 100 < density ]
[ sprout 1
[ set breed cons
set shape "circle"
set faction random factions
set heading random 360
set size 1
]
]
]
.. guessing I will have to do 360 / fractions, but not sure how to phrase it, if someone could help me out that'd be great. Thanks!
The NetLogo primitive that's the closest to what you want to do is in-cone, which reports the set of turtles that are in the "cone of vision" of another turtle. But your "pie slices" should just be relative to patch 0 0, not to another turtle! No problem: just make a temporary turtle at patch 0 0, use it to get turtles in-cone with the appropriate angle, and kill your temporary turtle.
The following procedure can be used "as is" with your code (just call it from your setup procedure after creating your turtles exactly as you were doing before):
to assign-factions
let angle 360 / factions
foreach n-values factions [?] [
ask patch 0 0 [
sprout 1 [
set heading ? * angle
ask turtles in-cone max-pxcor angle [ set faction ? + 1 ]
die
]
]
]
end
The code is pretty straightforward, except for maybe the more obscure n-values. You could replace it with a while loop if you prefer, but it's really just counting from 0 to factions.
Here is what you'd get with 5 factions: