Export part of the view in NetLogo - image

I want to, given a list of turtles, export the part of the view that contains those turtles as an image. Being able to export part of the view specified by a set of boundaries would solve this problem. That is, a function like export-view-of-turtles list-of-turtles or export-view-rectangle min-xcor max-xcor min-ycor max-ycor would be ideal.
Obviously, a solution that works entirely in NetLogo would be best, but I find that unlikely: export-view is the only function I know of that exports an image of the view at all, and that only does the whole view. However, if there's a plugin for this, that would be awesome.
My last resort is to just export the view and then run a script that clips it accordingly. If there isn't a better solution, I'll do this, and post the script.

Alright, this is kind of dirty, but it seems to work. Basically, the below exports the world state in a temp file, records the data about the turtles in question, resizes the view based on the distance of those turtles from the center, recreates just those turtles from the recorded data, exports the view, then restores the original world state. Here's the code:
to export-view-of-turtles [ filename the-turtles ]
let center-patch min-one-of patches [ sum [ (distance myself ^ 2) ] of the-turtles ]
let turtle-props [ (list
(- distance center-patch * sin towards center-patch) ; xcor relative to center patch
(- distance center-patch * cos towards center-patch) ; ycor relative to center patch
heading size shape label color
) ] of the-turtles
let max-x max map [ first ? + item 3 ? ] turtle-props
let min-x min map [ first ? - item 3 ? ] turtle-props
let max-y max map [ item 1 ? + item 3 ? ] turtle-props
let min-y min map [ item 1 ? - item 3 ? ] turtle-props
let world-state-backup (word "temp-world-" date-and-time ".csv")
export-world world-state-backup
resize-world min-x max-x min-y max-y
foreach turtle-props [
crt 1 [
setxy first ? (item 1 ?)
set heading (item 2 ?)
set size (item 3 ?)
set shape (item 4 ?)
set label (item 5 ?)
set color (item 6 ?)
]
]
export-view filename
import-world world-state-backup
file-delete world-state-backup
end
Example of use. Given:
Calling export-view-of-turtles "test.png" [ turtles in-radius 5 ] of turtle 85 gives:
Notes:
This perfectly supports world wrapping.
It will ONLY show the given turtles. Patches, drawing layer, and other turtles will not be shown. That said, it could easily be modified so that they patches and other turtles are shown.
As with any code that uses import and export world (not recommended for this kind of thing), this will likely break in many corner cases.

Related

How to create two different random color groups in NetLogo 6.1.1?

How to create two different random color groups in NetLogo 6.1.1?
I am trying to create two different groups from the group of 250 turtles. The starting situation is that all 250 turtles are gray and then they will turn to yellow and pink groups one by one.
This code of mine makes all turtles in the beginning to be gray and then they will all turn to pink. I do not want this but I want two randomly made groups where pink turtles is typically either larger or smaller group of turtles than the yellow group of turtles in the end of the code run.
I just started to code with NetLogo 6.1.1. Thank you for understanding and all help and have a nice day.
[
time
person
]
turtles-own [ x ]
to setup
clear-all
reset-ticks
set time 0
create-turtles 250
[
setxy random-xcor random-ycor
]
ask turtles
[
set shape "person"
set size 1
set color gray
]
end
to go
ask turtles
[
show random 2 = x
if x = 1 [set color yellow]
if x = 0 [set color pink]
]
end ```
I don't see any place where the values for the turtle variable x are set, so they will always have the default value of 0. In NetLogo = is used to check equality, not for assignment, so show random 2 = x is just going to print true or false depending on if random 2 is 0 or not (in case you thought that was assignment). You'd want something like this:
to go
ask turtles
[
set x random 2
if x = 1 [set color yellow]
if x = 0 [set color pink]
]
end
Or you could move the set x random 2 to the setup procedure if you just want to set the value once to use later in go.

Netlogo - find the closest agent based on Manhattan distance

I am modelling a big warehouse operations (see below pic).
I have implemented a vertex on each patch (green dots) and link them so that I could compute the shortest path (using dijkstra algorithm) from each vertex to all other vertices, stored in a table (dictionary) of each vertex. This process is done during setup stage and is quite time-consuming. Then the yellow inventory cells (rectangle) will issue the demand request for task fulfillment.
The forklift truck (some in the path) is assuming to stay put on one of the vertex (node) when it's not busy. When get the demand request, it will ask its current standing vertex (node) to get the starting_node and the end_node of the inventory cell it is going to. Then the forklift ask the starting_node to get the shortest path from its table to get the shortest path (combination of nodes) and drive to the end_node (the yellow cell).
Currently, the yellow cells just randomly pick free forklift truck in the warehouse. As a further development, I want to add the function that allows the yellow cell to identify the free truck that is closest to it based on the actual distance (not the euclidean distance built in Netlogo). As there are many trucks so it's not good to use "foreach" to loop through all available trucks and compute the actual distance using above method. You could use primitive "distance myself" to locate the truck quickly but that's not accurate. Is there a good way to identify the closest truck with a faster computational method?
I don't know if this would work with your current setup, but you may also find the nw extension helpful. For example, try this setup (I apologize for the length, just approximating your world):
extensions [ nw ]
breed [ nodes node ]
breed [ trucks truck ]
breed [ cells cell ]
to setup
ca
resize-world -29 29 -14 14
ask patches with [ ( pxcor mod 5 = 0 or pycor = 0 ) ] [
set pcolor grey
sprout-nodes 1 [
set size 0.5
set shape "circle"
set color green
]
]
ask nodes [
create-links-with turtles-on neighbors4 [
set color green
]
]
ask n-of 5 nodes [
hatch 1 [
set size 1
set color red
set breed trucks
set shape "car"
]
]
ask n-of 2 trucks [
set color blue
]
ask one-of nodes [
ask one-of neighbors with [ pcolor = black ] [
sprout-cells 1 [
set size 1.5
set shape "box"
set color yellow
]
]
]
reset-ticks
end
Gives a simple world like this:
You can use the nw extension to calculate the distances on the fly, rather than storing them in a per-cell table, and have the forklifts (trucks, here) follow the shortest path. More details in comments:
to summon-nearest-truck
; Treat blue trucks as 'empty' and ready to go to a cell
let ready-trucks trucks with [ color = blue ]
; Get the nodes associated with those ready trucks
let truck-proxies turtle-set map [ i -> [nodes-on patch-here] of i ] sort ready-trucks
; Randomly ask one of the cells to
ask one-of cells [
; Choose one of the neighboring road nodes as a proxy for distance calculation
let node-proxy one-of nodes-on neighbors4
; Get the node proxy to:
ask node-proxy [
; Find the nearest (by network distance) trucks, and select the node
; located on the same patch as that truck
let my-truck-proxy min-one-of truck-proxies [length ( nw:turtles-on-path-to myself) ]
; Get that truck-proxy node to generate the path to the original asking node
; and have the appropriate truck follow that path
ask my-truck-proxy [
; Generate the path to follow
let path-to-follow nw:turtles-on-path-to myself
; Highlight that path for visualization
ask turtle-set path-to-follow [
set color orange
]
; Get the truck ready to move
let ready-truck one-of trucks-here with [ color = blue ]
ask ready-truck[
set color yellow
]
; Move that truck along the path-to-follow
ask ready-truck [
foreach path-to-follow [
n ->
face n
move-to n
; For visualization only
wait 0.1
]
]
]
]
]
end
This has the yellow box summon the nearest truck based on the length of nw:turtles-on-path-to that is returned. That truck follows the path to the summoning node:

Ask a random number of turtles to do something?

I have two procedures for turtles but I need a random number of turtles to do one of the procedures and another number of random turtles to do the other procedure in equivalent parts.
So suppose i have a population of 40 turtles and I have the following procedures:
to move
ask turtles [
rt random-float 90 - random-float 90
fd 1
]
end
to bounce
ask turtles
[
if [pcolor] of patch-at dx 400 = white [
set heading (- heading)
]
if [pcolor] of patch-at 400 dy = white [
set heading (180 - heading)
]
]
end
What I want to do is to have 20 random turtles do the procedure "to bounce" and the other 20 random turtles do the procedure "to move". Or the 40 turtles will do any of the 2 procedures randomly but without any turtle doing the 2 processes at once.
I know this is kind of difficult but I think it can be done. Any suggestions?
This is the easiest way I can think of:
let bouncers n-of 20 turtles
ask turtles [
ifelse member? self bouncers
[ bounce ]
[ move ]
]
There's lots of interpretations of the phrase random number of turtles. Seth's method allows you to control exactly how many turtles do each of the two procedures. That is, a fixed number of random turtles.
If you want it always to be approximately, but not necessarily equal to, some proportion of turtles (0.4 in the example below), so each turtle randomly decides with a given probability, then you can do:
ask turtles [
ifelse-value random-float 1 < 0.4
[ bounce ]
[ move ]
]
If you want the number of turtles to be random, then you can change the first line of Seth's code to:
let bouncers n-of (1 + random count turtles) turtles
Note: none of this code is tested so please comment (or edit) if it throws an error.

Creating another kind of turtles in go button according to slider percentage

I am trying to create land use model in a city. Every GO or tick x percent (according to slider) migrants (turtles) will be sprouted in random patches which there are no turtles on it.
Currently I am still using below code, it doesn't use slider but specific number 1000 > 9 which is close to 2% according to number of turtles I created in setup.
to go
ask patches with [pcolor = green and any? turtles-here = false]
[ if random 1000 < 9 [sprout-migrants 1 [
set color red
set shape "default"
set size 1
set-income
find-residence]]]
tick
end
Assuming you have a slider named x that you want to control the percent change, then replace:
random 1000 < 9
with
random 100 < x
If the slider can take on non-integer values, then do
random-float 100 < x
you could also use this code. this way you don't need to run the if-statement to all of the patch.
assuming the slider is x as percent and turtle-numbers is contain the number of turtles you setup
let migrants-to-sprout ((x / 100) * turtle-numbers)
you set the number of turtles you want to sprout first and then make it as the loop indicator
repeat migrants-to-sprout [
ask patches with [pcolor = green and not any? turtles-here]
[
sprout-migrants 1 [...]
]
]

How to speed up least-cost path model at large spatial extents

Following on from How can I increase speed up simulation of my least-cost path model, I try to find a way to speed up my least-cost path model that runs at a large spatial scale. My landscape has an extent of 100kmĀ² (1000 patches x 1000 patches with 1 patch = 1 pixel).
For the moment, my code seems to work but it runs very slow: my code takes several hours to draw one least-cost path. The problem is that my model evolves according to discrete time steps of two minutes during 100 days and I have 1000 wolves in my landscape. For each wolf and at each time step, my model has to build the least-cost path between a polygon (composed of several patches) where there is a wolf and all polygons that are situated in a radius of 3km around the wolf.
I used the new version of NW-extension and I tried to optimize my model by saving all costs that have already been calculated to avoid to re-draw the least-cost paths. Unfortunately, my code is yet too slow and I don't know how to speed up it. Here is my code to calculate the cost of one least-cost path (If need be, I can provide more code to someone)
to-report path-cost-between-polygons [ID-polygon-1 ID-polygon-2]
let path-cost -1
;; Define polygon edges
ask patches with [ID-polygon != ID-polygon-1] [
ask neighbors with [ID-polygon = ID-polygon-1] [
ask nodes-here [
set color red ] ] ]
ask patches with [ID-polygon != ID-polygon-2] [
ask neighbors with [ID-polygon = ID-polygon-2] [
ask nodes-here [
set color red ] ] ]
;; Calculate path cost
foreach sort ( (nodes-on patches with [ID-polygon = ID-polygon-1]) with [color = red] ) [
let node-on-polygon-1 ?
foreach sort ( (nodes-on patches with [ID-polygon = ID-polygon-2]) with [color = red] ) [
let node-on-polygon-2 ?
ask node-on-polygon-1 [
let cost nw:weighted-distance-to node-on-polygon-2 "link-cost"
if path-cost = -1 or cost < path-cost [
set path-cost cost ] ] ] ]
;; Save path cost between polygons
set list-ID-polygons lput (list ID-polygon-1 ID-polygon-2) list-ID-polygons
set list-path-costs-between-polygons lput path-cost list-path-costs-between-polygons
ask nodes with [color = red] [ set color white]
report path-cost
end
Thanks very much for your help.
I'm currently working on a new version of the NW-extension that will be much faster. Unfortunately, for weighted paths, it won't be available till NetLogo 5.0.6 comes out.
Until then, you could code your own least-cost path code. A* would be perfect for your situation. Implementing would definitely be somewhat tricky, but doable. If I have the time, I'll give it shot and post it here.

Resources