I'm trying to make groups of four turtles rotate randomly around the center of the group, however I'm having trouble calculating said center. Group ids are sequential (eg turtles with [who] 0-3 are group 1, 4-7 are group 2 etc). Currently, my attempt at calculating the group center is as follows:
let i 0
while [i < group_num] [ ;;iterates over each group
;;setup some information about the group
let j 0
let cmx 0
let cmy 0
let cmz 0
while [j < 4] [
set cmx (cmx + (turtles ((i * 4) + j) xcor)) ;this doesn't work
;set cmy (cmx + (turtles with ((who = ((i * 4) + j)) ycor ))) ;nor does this
;set cmz (cmx + (turtles with ((who = ((i * 4) + j)) zcor )))
]
set cmx (cmx / 4)
set cmy (cmy / 4)
set cmz (cmz / 4)
;; rest of the program
]
Both the cmx and cmy line tell me that there's a missing closing parenthesis, but all parenthesis have a partner and the program highlights them as such. Any advice on how to call the position of a particular turtle?
Thanks in advance!
This is for NetLogo3D, correct? Maybe this base can get you on the right track. Some details in comments. With this setup:
turtles-own [ group-id static-center my-radius]
to setup
ca
let i 1
crt 16 [
set group-id i
if count turtles with [ group-id = i ] > 3 [
set i i + 1
]
set color 25 + ( 20 * group-id )
setxyz random-xcor / 2 random-ycor / 2 random-zcor / 2
pd
]
ask turtles [
; Identify the starting center of the group, as well
; as each turtles distance to that point
set static-center group-center
set my-radius distancexyz item 0 group-center item 1 group-center item 2 group-center
; Face the center point, then tilt up to be tangential
; to the circle the turtle should transcribe
facexyz item 0 static-center item 1 static-center item 2 static-center
tilt-up 90
ask patch item 0 group-center item 1 group-center item 2 group-center [
set pcolor [color] of myself
]
]
reset-ticks
end
That makes use of a group-center reporter that returns a list of the mean xyz coordinates of the group:
to-report group-center
let my-group turtles with [ group-id = [ group-id ] of myself ]
let group-x mean [xcor] of my-group
let group-y mean [ycor] of my-group
let group-z mean [zcor] of my-group
report ( list group-x group-y group-z )
end
And this is just a simple go for the turtles to tilt-down according to their radius.
to go
ask turtles [
tilt-down 180 / ( pi * my-radius )
fd 1
]
tick
end
Related
Suppose that the more common friends two nodes have, the more closely they are related. I want to find the closest link-neighbor of a node.
But it's difficult for me to find the common friends between one random nodes and its link-neighbors.
I wrote an example to see if my thought works:
turtles-own[CF] ;;common friends
to setup
ca
crt 10 [set size 1 set color gray]
ask turtle 1 [create-links-with other turtles]
ask turtle 2 [create-link-with turtle 3]
ask turtle 2 [create-link-with turtle 4]
layout-circle (sort turtles) 5
reset-ticks
end
to go
ask one-of turtles [
let communicator self
ask link-neighbors [;;setA
let i 0
ask link-neighbors [;;setB
if link-neighbor? communicator[
set i i + 1
]
]
set CF i
]
]
tick
end
In the interface, I set a reporter [CF] of turtle 2.If it works, the answer could be 2
But as it keeps going, the reporter shows sometimes 1 and sometimes 2. I don't know why and I hope sth more simple.
I haven't traced your code's operation, but your core structural problem is that "common friends" is a property of a PAIR of nodes, not one node .
I tweaked your code to set the common friends count ( CFL ) to the LINK between pairs of nodes. So (link 1 2) ends up with CFL = 2 and it's stable. It's not as efficient as it could be but then you can just run all the turtles, not one of the turtles in your go step.
Here's my solution:
turtles-own[CF] ;;common friends
links-own[CFL]
to setup
ca
crt 10 [set size 1 set color gray set shape "circle" set label who ]
ask turtle 1 [create-links-with other turtles set color green]
ask turtle 2 [create-link-with turtle 3 [set color orange set thickness 0.25] ]
ask turtle 2 [create-link-with turtle 4 [set color orange set thickness 0.25] ]
ask turtle 2 [ set color red ]
ask one-of links with [end1 = turtle 1 and end2 = turtle 3] [ set color green set thickness 0.25 ]
ask one-of links with [end1 = turtle 1 and end2 = turtle 4] [ set color green set thickness 0.25 ]
layout-circle (sort turtles) 5
reset-ticks
end
to go
let ln-direct ""
let ln-once-removed ""
ask turtles [
let communicator self
ask link-neighbors [;;setA
set ln-direct self
; print (word "for turtle " myself " one DIRECT link-neighbor is " ln-direct)
let i 0
ask link-neighbors [;;setB
set ln-once-removed self
; print ( word " one neighbor of that neighbor is " ln-once-removed )
if link-neighbor? communicator[
; print (word ",,,,,,,, BINGO - loops back to " communicator )
set i i + 1
]
]
ask one-of links with [
( end1 = communicator and end2 = ln-direct ) or
( end2 = communicator and end1 = ln-direct )
] [set CFL i set label CFL ]
]
]
tick
end
I would like to set a regular grid of turtles. With the following example, I have gotten to distribute the reader agents equally spaced in the x dimension, but I can not set a maximum number of agents per row and place the followings rows of readers in the world.
breed [readers reader]
globals [ reader-ycor ]
to setup
clear-all
setup-globals
setup-readers
end
to setup-globals
set-default-shape readers "square 2"
set reader-ycor (min-pycor + 1)
end
to setup-readers
let horizontal-interval (world-width / number-of-readers)
create-readers number-of-readers [
set color green
setxy (min-pxcor - 0.5 + horizontal-interval * (0.5 + who)) reader-ycor
set size 3
set label ""
]
end
to go
setup
end
The global number-of-readers indicates the total number of readers, and max-number-per-row would be a variable set to 10 (the maximum number of readers per row).
I do not know how to tell the x-coordinate to stop when a row has 10 readers and how to tell Netlogo to add a new row of readers when the who of a reader is greater than 10.
Regards
I think instead of using who numbers (which is not recommended) you might be better off just calculating the coordinates manually and then spawning the turtles on the calculated values. With this setup:
breed [ readers reader ]
to setup
ca
spawn-by-row
reset-ticks
end
And these sliders for readers per row and number of readers:
This code will build readers from the lowest x/y value (details in comments):
to spawn-by-row
; get the intervals
let h-int world-width / readers-per-row
let v-int world-height / readers-per-row
; Get a range of horizontal and vertical coordinates, starting at half
; of the interval value from the minimum x coordinate
let h-vals ( range ( min-pxcor + h-int / 2 ) max-pxcor h-int )
let v-vals ( range ( min-pycor + v-int / 2 ) max-pycor v-int )
; Create an empty list to build into
let possible-coords []
; For each possible vertical value, map all horizontal values in order and
; combine these into an ordered list starting at the lowest px and py coords
foreach v-vals [
v ->
set possible-coords ( sentence possible-coords map [ i -> (list i v) ] h-vals )
]
; Use the number of readers to sublist the possible coordinates, and
; create a turtle at each of the coordinate combinations left.
let use-coords sublist possible-coords 0 number-of-readers
foreach use-coords [
coords ->
create-readers 1 [
setxy item 0 coords item 1 coords
set shape "square 2"
]
]
end
If you have more number-of-readers than can be accommodated by readers-per-row you will throw an error, but that would be easily fixed.
Edit 2:
Add a slider for distance-var to the interface above, and try this modified version of spawn-by-row
to spawn-by-row
; Get a range of coordinate values
let half-step 0.5 * distance-var
let d-vals ( range ( min-pxcor + half-step ) ( max-pxcor ) distance-var )
; Create an empty list to build into
let possible-coords []
; For each possible vertical value, map all horizontal values in order and
; combine these into an ordered list starting at the lowest px and py coords
foreach d-vals [
d ->
set possible-coords ( sentence possible-coords map [ i -> (list i d) ] d-vals )
]
; Use the number of readers to sublist the possible coordinates, and
; create a turtle at each of the coordinate combinations left.
let max-positions length possible-coords
if max-positions > number-of-readers [ set max-positions number-of-readers ]
let use-coords sublist possible-coords 0 max-positions
foreach use-coords [
coords ->
create-readers 1 [
setxy item 0 coords item 1 coords
set shape "dot"
set color white
]
]
end
I have managed a solution but using the avoidable who numbers.
breed [readers reader]
undirected-link-breed [ rris rri ]
globals [ reader-ycor ]
to setup
clear-all
ask patches [ set pcolor blue - 3 ]
setup-globals
setup-readers
end
to setup-globals
set-default-shape readers "square 2"
set separation-distance-ratio 10 ; should be > 10
set number-of-readers 24
set interf-rri-radius 110
end
to setup-readers
let horizontal-interval (world-width / separation-distance-ratio )
let vertical-interval (world-height / separation-distance-ratio )
create-readers number-of-readers [
setxy (min-pxcor - 0.5 + horizontal-interval * (0.5 + who mod 10 ))
(min-pycor - 0.5 + vertical-interval * (0.5 + floor (who / 10) ) )
set size 2.5
set color green
]
ask readers [ create-rris-with other readers in-radius interf-rri-radius ]
end
to go
setup
end
I have a model in which a population is normally distributed across the patches. I used the following code to do that:
ask patches [
let x1 (pxcor - mean1) / sd-pop1
let y1 (pycor - mean2) / sd-pop1
set popualation ( (pop1) * exp (-0.5 * ( x1 ^ 2 + y1 ^ 2)) / (2 * pi * sd-pop1 ^ 2))
]
I want to distribute 10 turtles in a similar manner. In the attached image just as how the major chunk of the population is distributed across the patches close to the center of the grid space. Similarly of the 10 turtles to be created, i want a major chunk to be randomly spread across the population rich patches and a few which are spread on the periphery.
to setup-parties
create-parties Num-of-parties
let sp sqrt((((sd-pop1 ^ 2) * (pop1 - 1)) + ((sd-pop2 ^ 2) * (pop2 - 1))) / (pop1 + pop2 - 2))
ask parties [
ifelse (pop2 > 0) [ set heading random-float 360 jump random-float sp ] [ set heading random-float 360 jump random-float sd-pop1 ]
set size 3
set color random 130
set label who + 1
set label-color red
set my-old-size 1
set shape "default"
set old-x xcor
set old-y ycor
update-rule
]
end
I would use the rnd extension for this and select 10 patches (weighted by population) to sprout a turtle. Something like ask rnd:weighted-n-of 10 patches [ population ] [ sprout 1 ]. You will also need extensions [rnd] at the top of your code if you use this method.
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.
How do I implement a line of sight in NetLogo whereby
A turtle calculates/counts all turtles between it and the a given patch on the line of sight.
Thanks.
Let's say that each turtle has a turtles-own called target, which is the given patch, you can ask each turtle to face the target patch and count all the turtles between it and the given patch:
ask turtles [
face target
let n 1
let c 0
while [patch-ahead (n - 1) != target][
ask patch-ahead n [
if any? turtles-here [set c (c + 1)]
]
set n (n + 1)
]
print (word who " has " c " turtles on the line of sight")
]
A while loop doesn't look very clean in NetLogo but it works.
See Line of Sight Example, in the Code Examples section of NetLogo's Models Library.
Very similar to Dr_stein
To-report count-turtles-on-line-to[target]
Let c 0
Let d distance target
Face target
While d > 0
[
Let c c + count turtles-on patch-ahead d
Let d d - 1
]
Report c
End
I would suggest using the patches-ahead reporter from this answer:
to-report patches-ahead [ dist step ]
report patch-set map patch-ahead n-values (dist / step) [ step + ? * step ]
end
You can use it like this:
to setup
clear-all
create-turtles 100 [ setxy random-xcor random-ycor ]
ask turtles [
let target one-of patches
face target
show (word
count other turtles-on patches-ahead distance target 0.1
" turtles between me and " target)
]
end