I'd like to find the set of patches that constitute the convex hull around a set of patches belonging to the turtle's territory. I was planning to use a "gift wrap" procedure to calculate the convex hull (related to below picture).
I'm first finding the territory patch with the lowest pxcor to start at. Then, I'd like to find the territory patch that has the smallest heading (i.e., angle closest to zero) from the starting patch, and so on, until I arrive back at the starting patch. But I can't seem to figure out how to calculate headings between two patches. Any suggestions would be really helpful. Here is what I have so far. Eventually I will have to make this loop through each point along the outer hull.
patches-own [ owner-animal ]
turtles-own [ territory ]
to setup
ca
create-turtles 1
[
move-to patch-at (max-pxcor / 2) (max-pycor / 2)
set territory patches in-radius (2 + random 8)
ask territory [
set owner-animal myself
set pcolor [ color ] of myself - 2
]
]
end
to find-convex-hull
ask turtles
[
let start-patch min-one-of territory [pxcor]
ask start-patch
[
let next-patch min-one-of [territory] of myself [towards self]
]
]
end
I think this does what you're looking for. The only odd thing about the code is the [towards myself - heading] of myself] in which the first myself refers to the next turtle and the second myself refers to original, because it is the myself of the myself.
Does that make sense? Let me know if you have any questions.
to setup
ca
crt 10 [setxy random-xcor random-ycor]
end
to start-connecting
ask min-one-of turtles [xcor][set heading 0 connect]
end
to connect
let the-turtle min-one-of other turtles with [[towards myself - heading] of myself > 0] [ [towards myself - heading] of myself]
if the-turtle = nobody [stop]
face the-turtle
ask the-turtle [set heading [heading] of myself]
create-link-with the-turtle
ask the-turtle [connect]
end
By the way, if you only want to do this for particular agentsets, just change which turtles you connect with in the connect procedure.
Related
I am very new to Netlogo and I am trying to simulate culling of turtles within a certain region based on the characteristics of the patch. Within my model landscape, I have one single patch that is orange. I want 50% of turtles within 5 pixels of that patch to die. I would also like this process to continue every year after the first year of the simulation (this part I think I have). Can anyone help me?
if d = 10 [
if year >= 2 [
let ring nobody
set ring patches in-radius 5 patches with [pcolor = orange]
ask turtles-on ring [die]
]
]
in-radius reports agents that are within a certain distance from the caller, so the orange patch must be the one calling in-radius.
The code in your example is not reproducible, so I'll make an arbitrary example:
to setup
clear-all
ask one-of patches [
set pcolor orange
]
create-turtles 100 [
setxy random-xcor random-ycor
]
end
to go
ask patches with [pcolor = orange] [
ask turtles-on patches in-radius 5 [
if (random 2 < 1) [die]
]
]
end
Note that in-radius reports agents within a certain distance, where the unit of measure of distance is a patch`s side.
Identifying patches within a certain distance and then asking all turtles on those patches to die (as in the example above, which follows the approach in your question) has a different effect than asking all turtles within a certain distance to die.
Which of the two approaches fits your case is something that you have to decide. Below, the code that would address turtles directly:
to go
ask patches with [pcolor = orange] [
ask turtles in-radius 5 [
if (random 2 < 1) [die]
]
]
end
I want to compare the patches in a certain radius regarding the amount of a certain class of agents on them. The agents should move to the patch where the most agents (in this case humans) are. If they are already on the patch with the most humans then they must not move. I coded it and the humans group but most of them don't stay and run around in lines (one behind the other). Would be great if anyone of you could have a quick look at my code. Thanks
if Strategy = "Gathering-Simple" [
if ((count(humans-on max-one-of patches in-radius rad [count(humans-here)] )) ) >= count(humans-here) [
if count(humans-on patches in-radius rad) - count(humans-here) > 0 [
face max-one-of patches in-radius rad [count(humans-here)]
fd 1
]]
]
This is a complete working example that uses your code. Is this displaying the behaviour you mean? It does have turtles chasing each other.
to setup
clear-all
create-turtles 100 [ setxy random-xcor random-ycor ]
reset-ticks
end
to go
let rad 5
ask turtles
[ let target-patch max-one-of patches in-radius rad [count turtles-here]
if count turtles-on target-patch >= count turtles-here ; comment 1
[ if count turtles-on patches in-radius rad > count turtles-here ; comment 2
[ face target-patch
forward 1
]
]
]
tick
end
If so, have a look at the two lines I have comments on.
Comment 1: The >= means that, even if the turtles are already on the highest count patch, this condition will be satisfied because count turtles-here will be equal to the count of the turtles on the highest count patch (this patch).
Comment 2: This line means that as long as there are any turtles on any patch within the radius but not on the particular patch where the asking turtle is located, then the turtle will move forward.
If you want to only have turtles move if not on a maximum count patch, try this instead:
to setup
clear-all
create-turtles 100 [ setxy random-xcor random-ycor ]
reset-ticks
end
to go
let rad 5
ask turtles
[ let target-patch max-one-of patches in-radius rad [count turtles-here]
if count turtles-on target-patch > count turtles-here
[ face target-patch
forward 1
]
]
tick
end
I took out the = in the comment 1 line and removed the second condition entirely so now the turtles move if their current patch has fewer (strictly, not <=) turtles than the patch they've spotted.
I agree with the previous post, but have some additional information.
If you want to move entirely to the target patch on each iteration, instead of moving just one step towards the target patch, in the above answer you could replace the code which produces one step of motion
[ face target-patch
forward 1
]
with
[
move-to target-patch
]
I confirmed by experimentation that the results of the two methods of moving will produce similar but somewhat different results.
I'm creating a fish-tank style simulation in NetLogo. There are "prey", "predators", and "hidingspots".
The idea is that when a predator appears on the map, the prey will individually run the "hide" behavior and head to the nearest "hidingspot" - provided there are no predators between it and the "hidingspot".
to move-turtles
ask prey [
if (any? predators)
[
hide
stop
]
The relevant code to run the hide command.
to hide
face min-one-of hidingspot [distance myself]
set d distance min-one-of hidingspot [distance myself]
ask patches in-cone d 80
[ set pcolor yellow
if (any? predators-here)
[ ask prey
[ forward 1
set color red
output-print "DANGER"]]]
forward 1
end
The problem is that I do not know how to use the if statement in the "ask patches" properly. And therefore when one prey spots a threat all prey are running the else part of the statement rather than evaluating it individually.
How would I fix this?
Any help is appreciated.
You need to separate what you are asking the prey to do from what you are asking the patches to do. As King-Ink said, you are asking the patches to ask all the prey to do things.
The easiest way is to create a patchset for the 'danger' patches and then check if there's a predator on those patches. To do this, you want something like the following (note that this is a complete model, so you can copy this whole code into a new model and run it).
A couple of other things in your code that I cleaned up. I used let for the local variable d so that it doesn't have to appear in your globals. I asked for min-one-of only once and reused because otherwise a different hidingspot could be selected each time (if multiple at same distance). While this would not have caused an error this time (because the second selection is just to find the distance which is, by definition, the same), it is good practice.
breed [prey a-prey]
breed [predators predator]
breed [hidingspots hidingspot]
to setup
clear-all
create-predators 1 [setxy random-xcor random-ycor set color red]
create-prey 5 [setxy random-xcor random-ycor set color brown]
create-hidingspots 20
[ setxy random-xcor random-ycor
hide-turtle
ask patch-here [set pcolor green]
]
reset-ticks
end
to go
ifelse any? predators
[ ask prey [hide] ]
[ ask prey [swim] ]
end
to hide ; turtle procedure
let target min-one-of hidingspots [distance self]
let path patches in-cone distance target 80
ask path [ set pcolor yellow ]
if any? predators-on path
[ set color red
output-print "DANGER"
face target
]
forward 1
end
to swim
end
you are asking each prey to ask all prey to hide. If you drop the ask prey from the command all prey are running it should work fine and be a bit faster
to hide
face min-one-of hidingspot [distance myself]
set d distance min-one-of hidingspot [distance myself]
ask patches in-cone d 80
[set pcolor yellow]
if (any? predators-here)
[
forward 1
set color red
output-print "DANGER"
]
end
I would like to define neighbors using in-radius or distance. My solution so far is:
turtles-own [
my-neighbors
num-neighbors]
to setup
ca
crt 100 [
move-to one-of patches with [ not any? turtles-here ]
set my-neighbors (other turtles) in-radius 3
set num-neighbors count my-neighbors
]
end
The problem with this is that most of the turtles have between 0 to 4 neighbors, but a few of them have a relatively huge number of neighbors (e.g., 34 and 65). Those turtles are located close to the center of the world.
Any ideas about what I am doing wrong?
It has to do with the timing of side effects in your program.
Suppose that the very first turtle to move moves near the center. None of the other turtles have moved yet, so they're all still on patch 0 0 and set my-neighbors (other turtles) in-radius 3 will capture them all. And even after they move elsewhere, they will still be included in the first turtle's my-neighbors agentset.
You can avoid the problem by first moving all the turtles and then calculate their neighbors:
to setup
clear-all
crt 100 [
move-to one-of patches with [ not any? turtles-here ]
]
ask turtles [
set my-neighbors (other turtles) in-radius 3
set num-neighbors count my-neighbors
]
end
I'm new to Netlogo. Here I'm trying ask red turtles to move towards the hight conc. patches. yellow turtles do not move. I did that! but I also want to ask the red turtles to avoid the patches which have yellow or red turtles on them and move to the neighbor of high conc.. In my code I asked them to stop once they become next to an occupied patch just because I couldn't do it. I also want to avoid getting 2 turtles on the same patch at any time. Any one could help me with that please?
patches-own [conc]
to set-up
clear-all
ask patch random-pxcor random-pycor [
set conc 200
set pcolor scale-color red conc 0 1]
crt 5 [setxy random-xcor random-ycor set shape "circle" set color red]
crt 20 [setxy random-xcor random-ycor set shape "circle" set color yellow]
reset-ticks
end
to go
diffuse conc 0.1
ask patches [set pcolor scale-color red conc 0 1]
ask turtles with [color = red]
[ifelse not any? turtles-on neighbors
[if [conc] of max-one-of neighbors [conc] > conc [
face max-one-of neighbors4 [conc]
move-to max-one-of neighbors4 [conc]]]
[stop]
]
tick
end
I think your code would read a little nicer if you used let to avoid repetition, like this:
let target max-one-of neighbors [conc]
if [conc] of target > conc [
face target
move-to target
]
For some different possible approaches to enforcing a "one turtle per patch" rule, see the One Turtle Per Patch Example model, in the Code Examples section of NetLogo's Models Library.
I assume that ifelse not any? turtles-on neighbors is your attempt to make turtles avoid occupied patches. But as you've written it, it has a stronger effect than that — it makes it so that any turtle with an adjacent occupied patch won't move at all.
I think you may have meant something more like:
ask turtles with [color = red] [
let targets neighbors with [not any? turtles-here]
let target max-one-of targets [conc]
if target != nobody and [conc] of target > conc [
face target
move-to target
]
]
Hope this helps.