How to find the nearest patch in 3D model? - netlogo

How can a turtle find the nearest patch in 3D model? For 2D model, the code should be like this.
let nearest min-one-of (patches with [pcolor = green] ) [distance myself] ;
However, I tried to use distancexyz, and it does not work and it requires x, y and z coordinators. I am not sure how to get those coordinators of a turtle. Thanks.

The same code should work in 3D as in 2D.

distancexyz takes coordinates as arguments, not an agent (patches are agents). You want distance, as in distance nearest.

Related

NetLogo: Creating Variable from Distance to Specific Patch

I have an issue in Netlogo giving agents the variable with distance (in patches) to a chosen patch that is water.
The agents are supposed to act according to their distance to water.
I want the agent to find the closest patch that has water = true, calculate the distance to that patch and save that specific distance in a variable that may change if the agent moves.
So the way I went about this is as follows:
turtles-own
[
next-river-patch
distance-to-river
]
to go
ask turtles
;find closest patch that has water = true
;calculate distance to that patch and save it in the turtles-own variable "distance-to-river"
set next-river-patch (min-one-of patches in-radius 100 with [water = true] [distance myself])
set distance-to-river distance next-river-patch
;check whether there is water in peception radius
;and whether directed walk is initiated
ifelse random-float 1 > water-directedness
and
patches with [water = true] in-radius 300 = true
[walk-directed]
[walk-undirected]
tick
end
to walk-directed
;deviation of random normal is smaller, the further from next 1st order river and is raised by a high pioneering rate
;with half the distance of the perception radius of 300 resulting in a deviation of 45 degrees and
;a pioneering rate of 0.5 leading to no influence onto the final deivation and a pioneering rate of 1 doubling the deviation.
let deviation 90 * ( 1 - distance-to-river / 300) * ( 2 * pioneering-along-rivers)
face min-one-of patches with [ water = true][distance myself]
rt random-normal 0 (1 * deviation)
fd 1
end
to walk-undirected
ask turtles [
rt random-normal 0 (2.25 * descision-randomness * 100)
fd 1
;it turns into a cumulated normal direction (with the chance of moving straight ahead being highest) and the standard
;deviation being defined by the descision-randomness-slider, with default being 45° and max being 225°
]
end
so the issue I am having is that the line
"set next-river-patch (min-one-of patches in-radius 100 with [water = true] [distance myself])"
returns a variable containing
the coordinates of the next patch that is water. Anyhow, i dont want the coordinates, but the distance to that patch so that i can use it in my cumulated direction.
set distance-to-river distance next-river-patch does not work.
Does anybody have an idea as to why that could be? I am relatively new to NetLogo so the answer may possibly seem very obvious.
Thank you very much!
P.S.: Another, possibly unrelated issue with my model is that agents turn dozens of times before each tick instead of each agent doing a single turn before going forward by 1.
So if you happen to see the solution to that by looking over the code, i would also be forever grateful.
Easiest problem first:
Why are some turtles moving more than once per tick?
walk-undirected is called by turtles, and it does ask turtles. So every turtle is making every turtle so the action. It should be like the other procedure and just do that action, no ask.
patches ...... = true
This is an error. You are comparing the agentset made by patches with ... to the boolean value true. An agentset can never be true OR false. An agentset can be empty, or have one or more agents in it. The any? reporter is used to determine if an agentset has any members.
The main question
It looks like you are already doing what you are asking. The line starting set nearest-river-patch gets the nearest water patch, and the line set distance-to-river calculates the distance to that patch. Not that if there is not any water in radius 100, next-river-patch will be nobody.
I don't see anything that would give you the coordinates (as a list?). Maybe try some parentheses to make sure the reporters are being evaluated in the right order:
set next-river-patch (min-one-of ((patches in-radius 100) with [water = true]) [distance myself])
You could also use with-min
set next-river-patch one-of ( ( ( patches in-radius 100 ) with [ water = true ] ) with-min [distance myself] )
Otherwise, correct the other errors and see what happens.

Finding the distance to the next patch ahead of a given color in Netlogo

I'm trying to model predators hunting prey through a world filled with obstacles. In an obstacle free world, the predators go on random walks until prey fall within a certain detection radius (react-D), and then move towards the prey to capture. I guess there may be several ways to handle obstacles that block line of sight, but my initial efforts are along the following lines:
ifelse any? prey in-radius react-D
[let target min-one-of prey in-radius react-D [distance myself]
face target
...move towards target if it's closer than the nearest obstacle (blue patch) ahead
]
[continue to random walk, avoiding obstacles
]
The first condition of ifelse may need another ifelse. In any case I think I just need a distance of the nearest blue patch ahead to compare with the target distance, but it's not clear to me how I can get that from patch-ahead.
It would be nicer if I could put all this into the test of the first ifelse, but something like the following doesn't allow for patches that aren't blocking line of sight to the prey:
ifelse any? prey in-radius react-D and min-one-of (patches in-radius react-D with [pcolor = blue])[distance myself] > min-one-of (prey in-radius react-D) [distance myself]
Line of sight is actually really tricky to model in NetLogo. At the moment I do it by creating a turtle (invisible, separate breed called crawler) where the agent is that is looking and have the crawler move ahead in small steps checking the colour of the patch that it is on. That goes inside a while loop and the crawler stops when it finds the wrong colour or when it gets to the target distance. the crawler has to take small steps because crossing over the corner of a patch should still block it and it's a trade-off between resolution (how small the crawler step is) against efficiency.
You can almost certainly do the same thing by creating a patch-set as the union of patches found with patch-ahead of multiple distances like 0.1, 0.2, .... and then checking any? over that patch-set
My current solution, giving patches-own [ ob ] values of 1 to all obstacle patches, then using while to detect obstacles ahead:
to detect-ahead
let dist 1
let last-patch patch-here
while [dist <= react-D] [
let p patch-ahead dist
if p != last-patch and [ob] of p = 1 [
ask p [ sprout-markers 1 [ set color yellow ] ]
set last-patch p
]
set dist dist + 1
]
end
Then it should simply be a case of comparing min-one-of the marker agent set with the target. Obviously smaller increments would be good, as JenB says.

Tell agent to not cross a road in Netlogo model

I'm trying to add a condition that doesn't allow an agent to cross over a road. The road patches are set to color red. I can't seem to figure out how to get this condition to work. I ultimately want the agent to turn around if the road is in the patch ahead. Here is my net logo code so far.
to go
ask turtles [
move
]
tick
if ticks >= 60 [stop]
end
to move
ifelse random-float 1 < q
[
ifelse random-float 1 < w
[let target-patch max-one-of neighbors [veg-suitability]
face target-patch]
[let target-patch max-one-of neighbors [pelev]
face target-patch]
]
[
ifelse [pcolor] of patch-ahead 1 = red
[lt random-float 180]
move-to one-of neighbors
ldd-normal
]
end
to ldd-normal
let ldd-distance (ldd-scale)
fd ldd-distance
end
The logic of your move procedure is a bit confused I think. First you have a random chance to either move to a patch with a higher value of a variable of interest (with the uphill primitive) or, if the random draw fails, it moves to a random neighbour. If you don't want it to move onto a red patch then you need to test if the patch that is chosen is red, but you just move it without checking.
After you have moved the turtle, you then check the colour of patch-ahead. Your problem here is that patch-ahead depends on the direction the turtle is facing, which has nothing to do with the direction it has already been moving. You either make it turn (though it may not turn enough) OR move forward. So it never actually moves away.
I can't give you an actual answer because I don't know what your logic is supposed to be. But you could look at structures like:
move-to one-of neighbors with [pcolor != red]
Or, if there are enough red patches that it is possible that there aren't any non-red neighbours (which would cause an error if you tried to move to one), you could use:
let okay-patches neighbors with [pcolor != red]
if any? okay-patches [move-to one-of okay-patches]
Another option is that you only meant to face rather than move to the patch in the first sections of code, then test whether it is facing a red patch and turn around if it is.

Turtles move to nearest patch of a certain color - how can this process be sped up?

I am trying to build a butterfly movement model in which butterflies are attracted to patches of their host plant. This attraction is expressed as a probability which is stored in a variable called "attr-prob". If a butterfly is located within 25 m of a host-plant patch (pcolor = 9.9), it will move to the nearest host-plant patch with the probability of attr-prob.
I wrote the following code:
if (distance (min-one-of (patches with [pcolor = 9.9]) [distance myself]) ) <= 25
[if random-float 1 < attr-prob [move-to min-one-of (patches with [pcolor = 9.9]) [distance myself]]]
This code seems to be doing what I want it to do, however, when I add this part into my model, it slows it down immensely. Does anyone have any alternative suggestions for coding this that might be quicker?
I am running Netlogo in 64-bit Java.
Try something like this:
if random-float 1 < attr-prob [
let target-patch min-one-of (patches in-radius 25 with [pcolor = 9.9]) [distance myself]
if target-patch != nobody [
move-to target-patch
]
]
This should be faster for a couple reasons.
First, the fastest code is the code that never runs. So, doing the probability check at the very beginning allows you to skip computing the closest patch whenever you can.
Second, using in-radius upfront rather than checking the distance at the end reduces the number of patches that you're looking over. Basically, you'll only be checking the color and distance of the patches in the radius, rather than all of the patches in the world.
Finally, in your original code, you were finding the closest patch twice. Instead, you can store the patch in a local variable (target-patch in the code I provided) so you only have to find it once. This alone should double the speed of the code (depending on the value of attr-prob). It also increases readability.

Multi-variate turtle movement

I need some help with some coding that has me stumped!
I have flies (a turtle breed) on a field. The field has green patches (grass) and brown and grey patches (two types of dung). There is a "patches own" which is the age of the dung (green patches = 0 and brown and grey patches increase +1 per tick).
This is what I need to happen: the flies need to move to the freshest dung within a certain radius and remain there until the dung disappears. If there is no dung within the radius they must move about randomly.
The way I have been looking about it is to use some combination of an IF statement, radius function and the downhill function (however I am not sure if that lets me select a radius or not).
Any help would be greatly appreciated, thank you.
*I have recently made some advances. I can get the flies to move randomly within a radius, but I can't specify which patches within that area the flies are allowed to go to.
[move-to one-of patches in-radius 892]
I can also make it so the flies go to the patch with the lowest patches own, but cannot specify that this patch must be of a certain colour and within a certain radius.
[move-to min-one-of patches [dung-score]]*
It might help if you combine in-radius, min-one-of and with. eg:
move-to min-one-of patches in-radius 10 with [member? pcolor [brown green]] [dung-score]
if there's a chance that the with block might return an empty agentset, you might want to test for condition to avoid an error. eg:
let candidates patches in-radius 10 with [member? pcolor [brown green]]
if any? candidates [move-to min-one-of candidates [dung-score] ]