Computing an agent on the further ends of cone of vision - netlogo

Given:
The wall(grey agents) are in a constant place along the top of the
world.
The blue agents always directly below but at various
distances. But they be off to the side of the gap but nevertheless
can be rotated so that they face the gap.
That the cone of vision angle is same for all blue turtles.
In the above figures, the blue agent's cone of vision is depicted. I wish to calculate the grey wall which meet the ends of the cone of vision ,that is, one on right and one on left.Also could I somehow calculate the x-coordinate at that point. Not the grey agent's coordinate as that would be a approximation.
To Compute:
The x coordinates where the extremes of cone of vision intersect grey turtles. Or those grey turtles they intersect.
Rough Figure:
So I wish to compute x_1 and x_2 in the below figure.
One way could as suggested by #JenB to divide it into three cases and and calculate A in each case.(Primarily on left or right). Then use trigonometry. I am correct. Are there any other ways as well?

If this is a 2D problem, it is simply a case of intersecting lines.
I would avoid using multiple cases; that is very prone to errors.
You will have a line that describes your wall of turtles, and two lines that describe your FOV boundaries. You can formulate each of these three lines in parametric form as [o.x,o.y] + [v.x, v.y] * s, which is a fixed point [o.x,o.y] plus a normal vector [v.x,v.y] scaled by s.
The wall of turtles is only defined for a certain domain of 's'; let's say domain of wall.s = [0 to 0.4, and 0.6 to 1]
I would describe how to find the intersection points, but intersections of parametric 2D lines is pretty standard fare, and is better shown in a PDF, so I'll refer you to this...
http://www.ahinson.com/algorithms_general/Sections/Geometry/ParametricLineIntersection.pdf
(remember never to divide by zero)
Once you know the values of the scale parameters 'left.wall.s' and 'right.wall.s', you can tell whether the domain of the turtle wall is within the view of the player. Also you can determine the intersection points simply by plugging back into the parametric line formulas.

dwn's answer covers computing the precise point of intersection.
You said you were also interested in just finding out what patch the answer lies on. Here's code for that:
to setup
clear-all
create-turtles 1 [
set heading -30 + random 60
]
ask turtles [
;; show center of vision cone
ask boundary-patch [ set pcolor red ]
;; show edges of 20 degree vision cone
lt 10
ask boundary-patch [ set pcolor blue ]
rt 20
ask boundary-patch [ set pcolor blue ]
;; restore turtle's original heading
lt 10
]
end
;; answers the question, what patch on the top row of the
;; world is the turtle currently facing?
to-report boundary-patch ;; turtle procedure
let n 0
while [true] [
let target patch-ahead n
if target = nobody or [pycor = max-pycor] of target [
report target
]
set n n + 1
]
end
Sample result:
Of course, it would actually be computationally more efficient to compute the answer directly, via a formula. (With an optional rounding step at the end, depending on whether you want a point or a patch.) But this code shows how to do it without having to do any tricky math.

The following trigonometry approach(suggested by #JenB) works perfect:
to-report calx2 [x0 y0 x1 y1 A]
report x0 + (y1 - y0) * tan ( A + atan (x1 - x0) (y1 - y0))
end
to start
ask turtles[
set corner-1 list calx2 xcor ycor ([pxcor] of patch-goal)([pycor] of patch-goal - 0.4) (-45) ([pycor] of patch-goal - 0.4)
set corner-2 list calx2 xcor ycor ([pxcor] of patch-goal)([pycor] of patch-goal - 0.4) ( 45) ([pycor] of patch-goal - 0.4)
]
The problem just arises when the left edge goes beyond 180 and right edge go beyond 0. I didn't consider that cases. Anyways, the above code solves the problem.

Related

Compute weighted mean of headings

I have each patch holding two lists: directions and magnitudes. Both lists contain values that are computed based on nearby turtles:
directions contains the headings from the patch to the various turtles (so basically it is just the turtle's heading rotated by 180°);
magnitudes contains a value that is directly proportional to the turtles' mass and inversely proportional to the distance between the patch and the turtles;
The items of the two lists are coupled in their order, i.e. the first item of directions and the first item of magnitudes are computed based on the same turtle, the two second items are computed based on another turtle and so on.
What I want to achieve is to come up with two single patch-own values, my-direction and my-magnitude, representing in some way the weighted average of directions, where the weights are magnitudes.
To put it another way, I am thinking of this in terms of vectors: turtles are exerting on the patch a force that can be represented as a vector, always pointing in the direction of the turtle and with a certain intensity (the magnitude). The resulting vector (represented by my-direction and my-magnitude) should be the resulting average of these forces.
I have seen this question. It does not address the issue of a weighted average; however it mentions the concept of circular mean. I've delved into it a bit, but I'm not sure how to apply it to my case and even if to apply it: does it still apply even with the formulation of the problem in terms of vectors?
I've seen this question/answer on SE Mathematics where it is said that the average vector can be found by averaging x- and y-coordinates of the initial vectors. In my case, ideally all the pairs of values in the two lists form a different vector with origin in the patch at issue, with heading found in directions and length found in magnitude. I suspect I can find the coordinates of each vector by multiplying its sine and cosine by its magnitude, however at this point I'd use some guidance as I might be overcomplicating things (either from the maths perspective or the NetLogo perspective).
This one below is a reduced version of the code that brings to the point where target-patches (not focusing on all patches, in order to make it quicker) have the two lists populated.
globals [
target-patches
]
turtles-own [
mass
reach
]
patches-own [
my-direction
my-magnitude
directions-list
magnitudes-list
]
to setup
clear-all
set target-patches n-of 10 patches
ask target-patches [
set directions-list (list)
set magnitudes-list (list)
set pcolor yellow + 3
]
create-turtles 10 [
move-to one-of patches with [(not any? turtles-here) AND (not member? self target-patches)]
set mass (random 11) + 5
set reach (mass * 0.8)
set size (mass / 8)
set shape "circle"
]
populate-lists
end
to populate-lists
ask turtles [
let relevant-targets (target-patches in-radius reach)
ask relevant-targets [
set directions-list lput (towards myself) (directions-list)
set magnitudes-list lput (magnitude-based-on-distance) (magnitudes-list)
]
]
end
to-report magnitude-based-on-distance
report [mass] of myself / (distance myself * 1.2)
end
Your initial instinct is right. You can do something like
LET my-dx mean (map direction magnitude [ theta scalar -> scalar * sin theta ])
(I may have that map and anonymous syntax wrong please edit)
And do the same for my-dy using cos (edit: or maybe negative cos?)
patch-at my-dx my-dy is one way of getting the patch.
You can also do (atan my-dx my-dy) to gets the new direction
And distancexy my-dx my-dy to get the magnitude
Don’t remember if patch can use distancexy or patch-at, but hopefully so. Otherwise you have to use a helper turtle, and do the math yourself.
I think I did a orbital mechanics toy model once that did something like this. It’s hiding on turtlezero.com.

Move agent based on probability/point attribute value and point distance, NetLogo

I have the set of points implemented in netlogo and agents are moving from one point to another. Each point has a weight (number approximately between 0 and 9, its not a probability). What I want to made is a simple rule.
I want to give all points probability of visit by the value of weight.
So the next point which will be visited by agent should be calculated by the probability based on point weight and the closeness point (more close point - bigger probability), but that closeness isn't so much big factor as the point weight. For example, I would like to set in formula that closeness is twice lower factor then point weight.
I investigated rnd extension, but I am not sure how to append probabilities to points which I am having a lot (approximately around 250 points).
You're on the right track with the rnd extension. From that extension you need the weighted-one-of primitive and you just put the formula into the reporter block.
I think this is something like what you want. It's a complete model so you can run it and see what it does. The reporter block uses the weight and the distance in the probability. Since you want the probability to be larger for closer, then I have used the inverse of the distance, but you could simply subtract the distance from something like the maximum distance in the model. You will also need an appropriate scaling factor (replacing the 10 in my example) so that the weight is worth twice an average value of closeness.
extensions [rnd]
turtles-own [weight]
to testme
clear-all
create-turtles 10
[ setxy random-xcor random-ycor
set weight 1 + random 3
set size weight
set color blue
]
ask one-of turtles
[ set color red
let target rnd:weighted-one-of other turtles [ 2 * weight + 10 / distance myself ]
ask target [ set color yellow ]
]
end

Netlogo - make patches smaller to display clearly all agents ' locations clustered in a small area

I am modelling delivery system of a city. the delivery branch agent's location is based on the real world coordinates. How can I make a smaller netlogo world that can clearly display all the agents in a defined area (min-x: 113.783131, max-x: 114.42618; min-y: 22.476584, max-y: 22.809712)? The current netlogo world is simply too big to make each agents visible (they all clustered in a small point)
All you need to do is write a function that rescales your x and y coordinates into the NetLogo range. Then simply call that function whenever you refer to real world coordinates. See below for functions that are independent of the number of patches in your world. You may want to fiddle with the maximums and minimums in the functions if you want to get closer to or further away from the edge. Also, I would add an error check (so the function prints a meaningful message if you accidentally try to ask for coordinates outside your predefined max and min).
Run the testme to see what it does.
to testme
clear-all
create-turtles 1
[ setxy fix-x 113.8 fix-y 22.6 ]
create-turtles 1
[ setxy fix-x 114.49 fix-y 22.8 ]
end
to-report fix-x [#x]
let minx 113.5
let maxx 114.5
report ((#x - minx) / (maxx - minx)) * (max-pxcor - min-pxcor) + min-pxcor
end
to-report fix-y [#y]
let miny 22.45
let maxy 22.82
report ((#y - miny) / (maxy - miny)) * (max-pycor - min-pycor) + min-pycor
end
UPDATE from comments: If you actually have a GIS dataset, simply load that into NetLogo using the GIS extension and set the envelope. The world will adjust.

Netlogo: can I set the distance between turtles?

Netlogo: can I set the distance between turtles?
Hello,
I’m trying to create a model in which on each tick a turtle randomly chooses another turtle as a partner, and jumps to a specified distance of their partner (the distance that it’s given is based on a probability). It does not matter where it moves to, as long as the turtles are the specified distance apart.
I have tried to model this by creating a ‘jump-with-probabilities’ procedure, and defining distance the turtle jumps in the two ‘IID’ procedures:
to jump-with-probabilities ;; adds behaviours depending on how a random number compares with the odds.
ask turtles [
let random-fraction
random-float 1.0
if-else random-fraction <= 0.4
[ IID_10 ]
[ IID_50 ]
]
end
to IID_10
ifelse distance partner >= 10 ;; if the distance to their partner is larger than or equal to 10
[ jump (distance partner - 10) ] ;; TRUE - jump forward by the difference of distance partner & 10, so that the distance is now 10
[ jump (-1 * (10 - distance partner)) ] ;; FALSE - jump backward by the difference of distance partner & 10, so that the distance is now 10
end
to IID_50
ifelse distance partner >= 50 ;; if the distance to their partner is larger than or equal to 50
[ jump (distance partner - 50) ] ;; TRUE - jump forward by the difference of distance partner & 10, so that the distance is now 50
[ jump (-1 * (50 - distance partner)) ] ;; FALSE - jump backward by the difference of distance partner & 10, so that the distance is now 50
end
The problem with using this is that the distances between the turtles in the end are not the same as the distances that I specified. For example, Turtle 0 may jump towards Turtle 5 so that their distance is the specified 20. But, Turtle 5 will also jump towards its partner, which will change the distance between Turtle 0 and Turtle 5. I considered using ‘ask-concurrent’ instead of ask, but the problem remains, because I am telling the turtles to move a certain distance, rather than to move to a certain distance of their partner.
So my question is; is there a way that I can tell a turtle to be within a specified distance of another turtle? So that if the partner moves the turtle will move too to keep the distance at the specified length.
I thought it may be possible to use ‘move-to’ and add the specified distance somehow. Or alternatively, use ‘distance’ to set this between 2 turtles. It seems rather basic, but I have not been able to figure out how to do it!
Any help would be much appreciated!
There's possibly a better way, but I would do this by moving turtle B to where turtle A is (move-to turtleA), then giving it a random heading (set heading random 360) then moving it forward 10 (forward 10). You could also hide turtle B until you have finished moving it and then unhide it to make the visualisation neater. That sets up the relative position, then use Alan's suggestion of tie to hold the relative position.

Draw an arrow for a vector on the top of each of the turtles

I wish to draw an arrow at the top turtle representing a vector denoted by
[x1,y1] . The vector is of unit magnitude and the size of the arrow should not exceed that of the turtle.
The vector is stored in a list with two elements.
I don't wish to use the shape editor in netlogo to shape as arrow and then point the turtle in the heading denoted by the vector. The reason being I could draw one than 1 arrows for each turtle.
Edit:
Desired:
Bryan's answer gives the following:
Edit 2:
Video link : https://www.youtube.com/watch?v=9SVcLg4Oyoc&t=23 for better explanation.
Here's how I'd do it:
Make sure your turtles are all of one breed, say, particles, or whatever they represent. Create another turtles breed called vectors or something. These turtles are going to be the tip of your vectors but you'll use links to actually visualize the vectors. Now, you can create the vectors like so:
ask particles [
hatch-vectors 1 [
create-link-from myself
hide-turtle
]
]
To update the position of the vectors (given that the vector itself is stored in a turtle variable vec), you can do:
ask particles [
let abs-x xcor + first vec
let abs-y ycor + last vec
;; Since the particle is linked to the vector by a directed link, it's an out-link-neighbor
ask out-link-neighbors [ setxy abs-x abs-y ]
]
Edit in response to update:
That's tougher, since link shape editing is more limited than turtle shape editing. One possibility would be to set the shape of the vector turtles to an arrow head (you could either create a new such shape, or the default turtle shape could suffice). Rather than hiding the vectors, you'd then point them in the right direction. This can easily be done by having them face their link-partner and then turn around.
You may also want to switch from directed to undirected links to get rid of the arrow in the link itself. This should only involve minor code changes.