How can we implement a bidimensional collision on a NetLogo Billiards? - collision

We're two videogame design and development students and we have to make some program using NetLogo. Our idea was a Billiards, and we have done it as well as we could, but there's impossible for us to imagine how can we implement the bidimensional collision between the 16 balls of the game, when do they collide and what do we need to write to make it happen. We do not want you to make our work, but we will be grateful if you could tell us, more or less, how to do it easily, because that's new for us and we need something not to hard, this way we will be able to comprehend it better (If the solution is complicated, well, we don't care, we need to know it so go ahead!).
This is our NetLogo code so far:
breed [BALLS ball]
balls-own [speed velocity x-vel y-vel]
globals [points]
to setup
clear-all
setup-patches
setup-balls
set-default-shape balls "circle"
ask ball 0 [hatch 1
[
set breed turtles
fd 3
set color red - 1
ask myself [create-link-to myself [tie hide-link]]
]
]
reset-ticks
end
to setup-patches
ask patches [ set pcolor green ]
ask patches [if (pxcor > -25) and (pycor > 12)
[ set pcolor brown ]
]
ask patches [if (pxcor < 25) and (pycor < -12)
[ set pcolor brown ]
]
ask patches [if (pxcor < -21)
[ set pcolor brown ]
]
ask patches [if (pxcor > 21)
[ set pcolor brown ]
]
;Up left corner
ask patches [if (pxcor = -22) and (pycor = 13)
[set pcolor black]
]
ask patches [if (pxcor = -21) and (pycor = 13)
[set pcolor black]
]
ask patches [if (pxcor = -22) and (pycor = 12)
[set pcolor black]
]
;Up right hole
ask patches [if (pxcor = 22) and (pycor = 13)
[set pcolor black]
]
ask patches [if (pxcor = 21) and (pycor = 13)
[set pcolor black]
]
ask patches [if (pxcor = 22) and (pycor = 12)
[set pcolor black]
]
;Down left hole
ask patches [if (pxcor = -22) and (pycor = -13)
[set pcolor black]
]
ask patches [if (pxcor = -21) and (pycor = -13)
[set pcolor black]
]
ask patches [if (pxcor = -22) and (pycor = -12)
[set pcolor black]
]
;Down right hole
ask patches [if (pxcor = 22) and (pycor = -13)
[set pcolor black]
]
ask patches [if (pxcor = 21) and (pycor = -13)
[set pcolor black]
]
ask patches [if (pxcor = 22) and (pycor = -12)
[set pcolor black]
]
;Up hole
ask patches [if (pxcor = -1) and (pycor = 13)
[set pcolor black]
]
ask patches [if (pxcor = 0) and (pycor = 13)
[set pcolor black]
]
ask patches [if (pxcor = 1) and (pycor = 13)
[set pcolor black]
]
;Down hole
ask patches [if (pxcor = -1) and (pycor = -13)
[set pcolor black]
]
ask patches [if (pxcor = 0) and (pycor = -13)
[set pcolor black]
]
ask patches [if (pxcor = 1) and (pycor = -13)
[set pcolor black]
]
end
to setup-balls
create-balls 16
ask ball 0 [setxy 10 0]
ask ball 0 [set color white]
ask ball 0 [set heading angle]
ask ball 1 [setxy -10 0]
ask ball 1 [set color blue]
ask ball 2 [setxy -11 0.5]
ask ball 2 [set color blue]
ask ball 3 [setxy -11 -0.5]
ask ball 3 [set color blue]
ask ball 4 [setxy -12 1]
ask ball 4 [set color blue]
ask ball 5 [setxy -12 0]
ask ball 5 [set color black]
ask ball 6 [setxy -12 -1]
ask ball 6 [set color blue]
ask ball 7 [setxy -13 1.5]
ask ball 7 [set color blue]
ask ball 8 [setxy -13 0.5]
ask ball 8 [set color blue]
ask ball 9 [setxy -13 -0.5]
ask ball 9 [set color blue]
ask ball 10 [setxy -13 -1.5]
ask ball 10 [set color blue]
ask ball 11 [setxy -14 2]
ask ball 11 [set color blue]
ask ball 12 [setxy -14 1]
ask ball 12 [set color blue]
ask ball 13 [setxy -14 0]
ask ball 13 [set color blue]
ask ball 14 [setxy -14 -1]
ask ball 14 [set color blue]
ask ball 15 [setxy -14 -2]
ask ball 15 [set color blue]
end
to go
ask balls [setxy (xcor + x-vel)(ycor + y-vel)
set velocity 1.01
if(velocity > 1)[
set x-vel x-vel / velocity
set y-vel y-vel / velocity
]
]
ask ball 0 [set heading angle]
ask balls [
if pcolor = black [
setxy 10 0
set x-vel 0
set y-vel 0
set points points - 1
]
]
ask balls [
if pcolor = brown [
if pxcor > 21 [
set y-vel y-vel - 2 * y-vel
]
if pxcor > -21 [
set y-vel y-vel - 2 * y-vel
]
if pycor > 12 [
set x-vel x-vel - 2 * x-vel
]
if pycor > -12 [
set x-vel x-vel - 2 * x-vel
]
]
]
tick
end
to shoot
ask ball 0 [set x-vel (sin angle * (power / 100))
set y-vel (cos angle * (power / 100))
set speed power / 100
]
end
We know that this is probably not the better way to do it, but it works! The buttons that you need are setup, shoot, go, a monitor named points and two slippers named angle (0-360) and power (0-100).
We've done a lot of research, and we've got almost nothing. We've looked at the example from NetLogo library named: that it wasn't very useful for us. Also we've looked some links like https://gamedev.stackexchange.com/questions/7862/is-there-an-algorithm-for-a-pool-game/7901#7901 or Mass Ball-to-Ball Collision Handling (as in, lots of balls) but we can make our head around with all this. Like I said, we only need the turtles bidimensional collision, thanks for reading!

There's code for this, with correct physics, in the GasLab Circular Particles model in the NetLogo Models Library, under Sample Models -> Chemistry & Physics.
The math and the logic involved is rather complex, but there is a fair amount of explanation in the Info and Code tabs.

Related

Procedures and reporters with default valued arguments in NetLogo

I am new to NetLogo but coming from previous functional programming languages.
Is there a way to have default values in procedures and reporters? or the norm is to set up global variables for parameters?
Sadly, no, there is no built-in way to provide default values for procedure arguments, command or reporter. There is at least one alternative I can think of that might provide some of the benefit, but it's not quite the same.
You didn't provide code for what you're doing, so I'll make a toy example:
to setup
clear-all
make-colony (one-of patches with [pcolor = black]) 10 red 1
make-colony (one-of patches with [pcolor = black]) 10 blue 1
make-colony (one-of patches with [pcolor = black]) 10 green 1
make-colony (one-of patches with [pcolor = black]) 10 orange 1
make-colony (one-of patches with [pcolor = black]) 10 violet 1
make-colony (one-of patches with [pcolor = black]) 10 yellow 1
reset-ticks
end
to make-colony [colony-patch ant-count colony-color ant-size]
ask colony-patch [
set pcolor colony-color
sprout ant-count [
set shape "bug"
set color colony-color
set size ant-size
fd 1
]
]
end
You can "store" the default values using anonymous procedures, but that anonymous procedure will have a fixed number of arguments it takes for the non-default values. Below I have the "regular" method from the starting example, but I build an anonymous procedure that provides the common arguments except for the color. You could store that make-regular-colony anonymous procedure in a global variable if you wanted to use it in multiple locations in code, you'd just have to make sure it's always set before running that code (setup after the clear-all is a good place).
to setup
clear-all
let make-regular-colony [ c -> make-colony (one-of patches with [pcolor = black]) 10 c 1 ]
(run make-regular-colony red)
(run make-regular-colony blue)
(run make-regular-colony green)
(run make-regular-colony orange)
(run make-regular-colony violet)
(run make-regular-colony yellow)
reset-ticks
end
to make-colony [colony-patch ant-count colony-color ant-size]
ask colony-patch [
set pcolor colony-color
sprout ant-count [
set shape "bug"
set color colony-color
set size ant-size
fd 1
]
]
end
This example isn't great, because you could just use foreach like foreach [red blue green orange violet yellow] [ c -> make-colony ... ] to get the same effect, but hopefully it makes the idea clear.

Releasing two turtles per tick netlogo

I'm currently working on a model where I could simulated pedestrian movement while shopping. So, I have already figure some of things I need but I have been trying to figure out how to release 2 turtles per tick (like a pair) in a certain patch. Both turtles are release at the same time. My code is base from ant lines but it just releases all the num-of-pedestrians in one time and then the turtles start walking. the ticks also start after all turtles are release. I want the turtles to start "walking" as they enter.
Here is my code:
breed [ leadvisitors leadvisitor ]
breed [ visitors visitor ]
to setup
clear-all
setup-visitors
reset-ticks
end
to setup-visitors
create-leadvisitors num-of-pedestrians * 0.1 ;;create 10% of the total number of pedestrians
[
set demand-type "none"
set color black
set size 1
setxy 0 16
set heading 180
set pen-size 1
set destination one-of patches
set wait-time -1
set demand-lvl 0
]
create-visitors (num-of-pedestrians - (num-of-pedestrians * 0.1))
[ set demand-type 0
set size 1
setxy 0 16
set heading 180
set pen-size 1
set destination one-of patches
set wait-time -1
set demand-lvl 1
set attracted? false
] ]
end
to go
if turtles = 0 [ stop ]
ask turtles
[
set-demand-type
have-demand
]
if ticks > 100 [ stop ]
tick
display-labels
end
;;;;; visitor's internal state of demand ;;;;;
to set-demand-type
if demand-type = 0
[ set demand-type "food"
set color red
let target (patches in-cone visitor-vision-depth visitor-view-angle) with [pcolor = red]
]
end
to have-demand
if demand-lvl = 0
[
ifelse wait-time = -1
[ stroll ]
[ set wait-time wait-time - 1
if wait-time = 0
[ stroll ]]
]
if demand-lvl = 1
[ ifelse wait-time = -1
[ stroll
evaluate ]
[ set wait-time wait-time - 1
if wait-time = 0
[ stroll
evaluate ]]
]
end
to stroll
if any? neighbors with [ pcolor = gray - 3 ]
[ die ]
ifelse any? neighbors with [ pcolor = gray or pcolor = orange or pcolor = blue or pcolor = red]
[ facexy exitpt-x exitpt-y ]
[ rt random-float visitor-view-angle lt random-float visitor-view-angle ]
fd walking-speed
end
to evaluate
if any? neighbors with [ pcolor = gray or pcolor = orange or pcolor = blue or pcolor = gray - 4 or pcolor = gray - 3 or pcolor = red + 2]
[ facexy exitpt-x exitpt-y
rt random-float visitor-view-angle lt random-float visitor-view-angle
fd walking-speed ]
let _mycolor color
if any? (patches in-cone visitor-vision-depth visitor-view-angle) with [pcolor = _mycolor]
[ let new-target max-one-of ( patches with [pcolor = _mycolor] in-cone visitor-vision-depth visitor-view-angle) [patch-influence]
let dist-to-new-target min-one-of (patches with [pcolor = _mycolor] in-cone visitor-vision-depth visitor-view-angle) [distance myself]
face new-target
set heading towards new-target
fd walking-speed
set attracted? true
attracted-and-visiting
re-evaluate
]
end
to attracted-and-visiting
if pcolor = red + 2
[ set heading towards one-of patches with [pcolor = red + 2]
fd 0
set patch-popularity patch-popularity + 1
set wait-time avg-waiting-time
if count turtles-here > 0
[ set num-of-visitors num-of-visitors + 1 ]
set plabel num-of-visitors
]
end
to re-evaluate
let _mycolor color
if not any? (patches in-cone visitor-vision-depth visitor-view-angle) with [pcolor = _mycolor]
[ set attracted? false ]
ifelse choose? [set heading towards one-of patches with [pcolor = _mycolor]] [facexy exitpt-x exitpt-y]
end
to-report choose?
report random 2 = 0
end
As a result of our back-and-forth comments, let me take a stab at what you are looking for. I assume that you want to create leadvisitors at the beginning of the run and then add two visitors per tick as the run progresses. If so, then your setup procedure would look something like
globals [num-visitors-created]
to setup
clear-all
set num-visitors-created 0
create-leadvisitors num-of-pedestrians * 0.1 [
set demand-type "none"
set color black
set size 1
setxy 0 16
set heading 180
set pen-size 1
set destination one-of patches
set wait-time -1
set demand-lvl 0
set num-visitors-created num-visitors-created + 1
]
reset-ticks
end
creating your leadvisitors, but no visitors. Note that the global variable num-visitors-created keeps track of the number of leadvisitors and visitors created, being incremented by one each time a leadvisitor or visitor is created.
In your go procedure, you would then create two visitors each tick until the total number of visitors and leadvisitors created reaches num-of-pedestrians. (If there is room for only one new visitor, would you want just one to be created, or do they need to be created in pairs? I'm assuming the latter.) Since you don't want the death of a visitor to open up space for a new one, we test the number created, not the number still alive.
to go
if turtles = 0 [ stop ]
; create a new pair of visitors if there is room.
if num-visitors-created <= (num-of-pedestrians - 2)
create-visitors 2 [
set demand-type 0
set size 1
set heading 180
set pen-size 1
setxy 0 16
set destination one-of patches
set wait-time -1
set demand-lvl 1
set attracted? false
set num-visitors-created num-visitors-created + 1
]
ask turtles
[
set-demand-type
have-demand
]
if ticks > 100 [ stop ]
tick
display-labels
end
(Since it appears that leadvisitors may die as well, do you want to keep a certain minimum number or proportion of leadvisitors? If so, you should open up a new question.)
The code above will create the pair of new visitors on patch 0 16 at each tick. If, however, you want to have the new visitors created on a different patch, say one of the red ones, you could in your go procedure have that patch sprout the new visitors.
ask one-of patches with [pcolor = red] [
sprout-visitors 2 [
set demand-type 0
set size 1
set heading 180
set pen-size 1
set destination one-of patches
set wait-time -1
set demand-lvl 1
set attracted? false
set num-visitors-created num-visitors-created + 1
]
]
Note that here the xy coordinates of the new visitors are not set, so they start on the patch that sprouted them.

NetLogo: setup-patches created after Tools -> Halt is used?

I my model I have several version of how my world should look like. I implemented this as "chooser" including choices:
"single_tree"
"clustered". My world is 501 * 501 patches.
When I run setup of my both variations, they are not created until I press Tools -> "Halt".
I don't really understand why because on my working model this works fine. Also when I run this "world variations" with basic paramaters - just with [set pcolor ...].
Please what can be bad in my model or what am I doing wrong?
here is the working example - works fine:
to setup-patches ; define patchy landscape
ask patches [
; Single tree
; -------------------------
if world = "single_tree" [
set pcolor green
]
; Clustered trees
; -------------------------
if world = "clustered" [
set pcolor red
]
end
here is little bit more complicated code but I don't see any reason for taking so long time for dispaying..
to setup-patches ; define patchy landscape
ask patches [
; Single tree
; -------------------------
if world = "single_tree" [
ask patches with [pxcor mod 50 = 0 and pycor mod 50 = 0] [
set pcolor red
]
]
; Clustered trees
; -------------------------
if world = "clustered" [
ask patch 0 0 [
ask patches in-radius (2.99 * Grid) with [pxcor mod Grid = 0 and pycor mod Grid = 0] [
set pcolor red
]
]
; ; determine cluster size
ask patches with [pcolor = red] [
ask patches in-radius radius [
set pcolor yellow
]
]
]
end
I really appreciate any suggestions and thank you a lot !
My problem was that I used too many times "ask patches" to "ask patches" to do something...
the fixed code is here - with ask patches only once per if statement:
to setup-patches
if world = "single_tree" [
ask patches with [pxcor mod 50 = 0 and pycor mod 50 = 0] [
set pcolor red
]
]
if world = "clustered" [
ask patch 0 0 [ ask patches in-radius (2.99 * Grid) with [pxcor mod Grid = 0 and pycor mod Grid = 0] [
set pcolor red
]
]
ask patches with [pcolor = red] [
ask patches in-radius 5 [
set pcolor yellow
]
]
]
end

setting variable in netlogo ifelse function and making turtle to wait in the patch

I have the following in netlogo
ask m-depts [ ; this check the values of turtles against some set numbers
ifelse
(m- k >= 5) and (m-t >= 3) and (m-c >= 3 ) and (m-s >= 4) and (m-b >= 3) and (m-d >= 0) [
move-to one-of patches with [pcolor = yellow]
] [
ifelse
(m-k >= 5) and (m-t >= 5) and (m-c >= 5 ) and (m-s >= 5) and (m-b >= 3) and (m-d >= 1) [
move-to one-of patches with [pcolor = green]
] [
action-m-depts
] ]]]
]
1st I want to add some conditions (set ……… ) if the turtle will move to yellow and also some other condition if it will move to green eg
If pcolor = yellow [
set m-k m-k + 0.5
set m-t m-t + 1
] ;
If pcolor = green [
set m-k m-k + 0.8
set m-t m-t + 2
] ; etc otherwise do action-m-depts (defined elsewhere)
2nd For the next move (ticks) I want to fix the turtle to wait at the patch eg (for yellow patch, wait for 5 years (5 ticks) and for green patch wait for 2 year (2 ticks). How should I incorporate the two issues in this model?
The code you have for the first part looks good to me. Have you tried it? I say go for it!
The second part is very similar to netlogo: how to make turtles stop for a set number of ticks then continue and Making turtles wait x number of ticks — check out those answers.

Netlogo, creating obstacle avoidance algorithm

I am simulating pedestrian motion in NetLogo, and am having trouble creating an obstacle avoidance algorithm from scratch. There are algorithms online but they are not suited for moving obstacles (other pedestrians). In addition, my agents are moving from their spawnpoint (point A) to their goal (point B).
This is my NetLogo algorithm:
globals [ wall walkway center dest ]
turtles-own [ gender goal velocity spawnpoint mid turn ]
to setup
clear-all
ask patches[
set wall patches with [
(pxcor > 3 and pycor > 3) or
(pxcor < -3 and pycor > 3) or
(pxcor < -3 and pycor < -3) or
(pxcor > 3 and pycor < -3)
]
set walkway patches with [
(pxcor > -4 and pxcor < 4) or
(pycor > -4 and pycor < 4)
]
set center patch 0 0
]
ask patches [
set pcolor black
]
ask walkway [
set pcolor 9
]
crt population [
set velocity 0.1
set mid 0
set gender random 2
if gender = 0 [set color red]
if gender = 1 [set color blue]
set spawnpoint random 4
if spawnpoint = 0 [ move-to one-of walkway with [not any? turtles-here and (pxcor < -11)]]
if spawnpoint = 1 [ move-to one-of walkway with [not any? turtles-here and (pycor > 11)]]
if spawnpoint = 2 [ move-to one-of walkway with [not any? turtles-here and (pxcor > 11)]]
if spawnpoint = 3 [ move-to one-of walkway with [not any? turtles-here and (pycor < -11)]]
set goal random 4
while [ goal = spawnpoint ] [ set goal random 4 ]
if spawnpoint != 0 and goal = 0 [set goal patch -16 0]
if spawnpoint != 1 and goal = 1 [set goal patch 0 16]
if spawnpoint != 2 and goal = 2 [set goal patch 16 0]
if spawnpoint != 3 and goal = 3 [set goal patch 0 -16]
]
reset-ticks
end
to decelerate
ifelse velocity > 0.01
[ set velocity velocity - 0.01 ]
[ rt 5 ]
end
to accelerate
if velocity < 0.1
[ set velocity velocity + 0.01 ]
end
to go
ask turtles [
ifelse patch-here != goal[
set turn random 2
if distance center < 3 [ set mid 1]
if mid = 0 [ set dest center ]
if mid = 1 [ set dest goal ]
face dest
ifelse any? other turtles-on patches in-cone 1.5 60
[ if any? other turtles-on patches in-cone 1.5 60
[ bk velocity
rt 90 ] ]
[ accelerate
face dest
fd velocity ]
]
[ die ]
]
end
The simulated environment of this simulation is an intersection:
http://imgur.com/nQzhA7g,R5ZYJrp#0
(sorry, I need 10 rep to post images :( )
Image 1 shows the state of the environment after setup. Image 2 shows what happens after the agents move to their goal (goal != their spawnpoint). The agents facing the different directions shows the agents which made its way past the clutter of agents in the center and are now on the way to their goal. The agents in the center, however, are stuck there because of my algorithm. The simulation is more problematic when there are more number of agents, which means they will just clutter in the center of the environment and just stutter when moving.
I based my algorithm on http://files.bookboon.com/ai/Vision-Cone-Example-2.html . Forgive my algorithm, I started programming in NetLogo a week ago and until now I still don't have the proper mindset in programming in it. I'm sure there's a better way to implement what I have in mind, but alas I am frustrated upon trying many implementations that came to my mind (but never got close to the real thing).
P.S: This is my first post/question in StackOverflow! I hope my question (and my way of asking) isn't bad.
Here is the simplest working version I could come up with:
turtles-own [ goal dest velocity ]
to setup
clear-all
let walkway-color white - 1
ask patches [
set pcolor ifelse-value (abs pxcor < 4 or abs pycor < 4) [ walkway-color ] [ black ]
]
let goals (patch-set patch -16 0 patch 0 16 patch 16 0 patch 0 -16)
ask n-of population patches with [ pcolor = walkway-color and distance patch 0 0 > 10 ] [
sprout 1 [
set velocity 0.1
set color one-of [ red blue ] ; representing gender
set dest patch 0 0 ; first head towards center
set goal one-of goals with [ distance myself > 10 ]
]
]
reset-ticks
end
to go
ask turtles [
if patch-here = goal [ die ] ; the rest will not execute
if dest = patch 0 0 and distance patch 0 0 < 3 [ set dest goal ]
face dest
if-else any? other turtles in-cone 1.5 60
[ rt 5
bk velocity ]
[ fd velocity ]
]
tick
end
Aside from the fact that I completely rewrote your setup procedure, it's not that different from your own version. I think your main problem was backing before turning: since you face dest again at the beginning of the next go cycle, your rt was basically useless.

Resources