Report specific patches around a given turtle - netlogo

How can I use the function neighbors to report at once all patches that are located around each turtle according to this image?
Just note that in the example as detailed below, row and column start from upper-left corner of the world. Thus, (1,1) is the upper-left patch index.
By supposing that a turtle A (red cross in the image) is located at the patch x0 y0, the neighboring patches around this turtle will be:
%%% Direction 1: patches at the upper-left corner
show patch (x0 – 2):(x0 – 1) (y0 – 2):(y0 – 1) which returns the patches with coordinates (1,1), (1,2), (2,1), (2,2)
%%% Direction 2: patches at the upper-middle corner
show patch (x0 – 2):(x0 – 1) (y0 – 1):(y0 +1) which returns the patches with coordinates (1,2), (1,3), (1,4), (2,2), (2,3), (2,4)
%%% Direction 3: patches at the upper-right corner
show patch (x0 – 2):(x0 – 1) (y0 + 1):(y0 + 2) which returns the patches with coordinates (1,4), (1,5), (2,4), (2,5)
%%% Direction 4: patches at the left corner
show patch (x0 – 1):(x0 + 1) (y0 – 2):(y0 – 1) which returns the patches with coordinates (2,1), (2,2), (3,1), (3,2), (4,1), (4,2)
%%% Direction 5: patches at the right corner
show patch (x0 – 1):(x0 + 1) (y0 + 1):(y0 + 2) which returns the patches with coordinates (2,4), (2,5), (3,4), (3,5), (4,4), (4,5)
%%% Direction 6: patches at the bottom-left corner
show patch (x0 + 1):(x0 + 2) (y0 - 2):(y0 - 1) which returns the patches with coordinates (4,1), (4,2), (5,1), (5,2)
%%% Direction 7: patches at the bottom-middle corner
show patch (x0 + 1):(x0 + 2) (y0 - 1):(y0 + 1) which returns the patches with coordinates (4,2), (4,3), (4,4), (5,2), (5,3), (5,4)
%%% Direction 8: patches at the bottom-right corner
show patch (x0 + 1):(x0 + 2) (y0 + 1):(y0 + 2) which returns the patches with coordinates (4,4), (4,5), (5,4), (5,5)

You could build something around the use of patch-at:
to setup
clear-all
create-turtles 1 [ setxy 3 3 ]
ask turtles [
show patches-at [[-2 0] [-1 0] [0 -2] [0 -1]]
]
end
to-report patches-at [ list-of-xy-pairs ]
report patch-set map get-patch-at list-of-xy-pairs
end
to-report get-patch-at [ xy-pair ]
report patch-at first xy-pair last xy-pair
end

Related

How can I compute the plotting of a triangle given it's vertices on matlab?

Given the vertices of the triangle (x1, y1), (x2, y2) and (x3, y3), how can I plot a triangle in matlab with a function? So far this is my attempt
function dibujatriangulo(x1,y1,x2,y2,x3,y3)
x=x2:x1
plot(x, y2+(x2-x1)/(y2-y1)(x-x2)
and likewise with the x2 and x3 and, x3 and x1 but it doesn't plot correctly. Any help would be appreciated.
As suggested by #BillBokeey, plotting a triangle is indeed a matter of understanding the plot function. In essence, plot(x, y) connect the subsequent points specified by the lists x and y with line segments. The code below illustrates this in more detail. I hope this helps.
% Call plot function
PlotTriangle(0,0,1,0,0,1)
% Function to plot triangle
function [] = PlotTriangle(x1,y1,x2,y2,x3,y3)
xlist = [x1, x2, x3, x1];
ylist = [y1, y2, y3, y1];
plot(xlist, ylist)
axis([-2, 2, -2, 2])
end
you can also use command patch
example
x=[0 1 .5];y=[0 0 1];
patch(x,y,[1 0 0])
the 3rd field colours the patch with red, the 3 components being red green blue desired contents each within range [0 255].
With patch you can plot any polygon, not just triangles.

Projections' Angle of Line in Space

Start of line (yellow) and axes are at [xc,yc,zc]
End of line is at [xp,yp,zc].
a,b, c are the angles which line makes in space.
What I need are the angles which line's projections (black line) create on xy,yz and xz planes.
A_y_to_z: Projected line's angle from y axis to z axis on xz plane.
A_z_to_x: Angle from z to x axis on zx plane.
A_x_to_y: Angle from x to y axis on xy plane.
Writing code on Matlab
You can calculate the projection angle to any plane by:
Obtaining the direction of the line, d = (xp - xc, yp - yc, zp - zc)
Normalizing d
Calculating the dot-product with the normal of the plane, dot(d, n) = d.x * n.x + d.y * n.y + d.z * n.z
Calculating the angle to the normal by a = acos(dot(d, n))
Finally obtaining the angle to the plane by taking b = 90 - a (assuming units in degrees - NB most math library functions use radians)
Special case: if dot(d, n) < 0, then the angle a will be greater than 90 degrees. In this case if you only want the acute angle, do b = a - 90 instead of 90 - a.
e.g. To calculate the angle to the xy plane, use n = (0, 0, 1), i.e. the z-axis, which is the normal to that plane.

Create Circle In 3-D Axes

I am newbie in matlab.
I want to draw something like below pic in 3-D axes and move it mouse move.
i do not have problem with second part(move objects on mouse move) ,
i do not know how to create this circle in 3-D axes
elevation = linspace(0,2*pi,100);
r = ones(1,100);
azimuth = .75 * pi *ones(1,100);
while 1
axis([-10 10 -10 10 -10 10])
view([20 20 5])
[newx newy] = ginput(1);
[x,y,z] = sph2cart(azimuth,elevation,r);
x = x + newx;
y = y + newy;
patch(x,y,z,[1 0 0],'EdgeColor','r');
axis([-10 10 -10 10 -10 10])
end
You can change the radius by r like r = .5 * ones(1,100);
But the coordinates of click doesn't seem to be right.
I think you have solved that problem in your previous question.
Note
Coordinates returned by ginput are scaled to the XLim and YLim bounds of the axes you click (data units).
The figure CurrentPoint property, by contrast, is always returned in figure Units, irrespective of axes Units or limits`

Draw circle with 100 points

I have to draw a circle using only 100 points. The center's coordinates are like (1,1), (1,2), (2,2) etc. The circle should be inscribed within 0.6×0.6 square. I figured out I can use something like:
th= linspace(0,2*pi)
to get 100 points, and
x = cos(th)
y = sin(th)
to get x and y coordinates to be used in plot(x,y).
However, I do not know how to get the exact coordinates or 0.6×0.6 square. If there was not np requirement of exactly 100 points I could use circleplot syntax...
You could do it like this (for each circle):
th = linspace(0, 2*pi);
x = sin(th) * .3 + cX;
y = cos(th) * .3 + cY;
plot(x,y);
where cX and cY are the center of the circle.

Efficient code for draw a sierpinski triangle with matlab

Following is my code:
function sierpinski(A, B, C, n)
if n == 0
patch([A(1), B(1), C(1)], [A(2), B(2), C(2)], [0.0 0.0 0.0]);
else
sierpinski(A, (A + B)/2, (A + C)/2, n-1);
sierpinski(B, (B + A)/2, (B + C)/2, n-1);
sierpinski(C, (C + A)/2, (C + B)/2, n-1);
end
% sierpinski([0 0], [1 0], [.5 .8], 8)
It's not very effectly. I want to first generating all data then patched, but I don't know how to correctly used. Also, can my code be written use for loops?
Your idea to write one function to generate the data and another to plot it is a good one - it's often a good idea to separate data generation from processing, and processing from output. I would do it something like this:
function out = sierpinski(a, b, c, n)
if n == 0
out.xvals = [a(1), b(1), c(1)];
out.yvals = [a(2), b(2), c(2)];
else
out1 = sierpinski(a, (a+b)/2, (a+c)/2, n-1);
out2 = sierpinski(b, (a+b)/2, (b+c)/2, n-1);
out3 = sierpinski(c, (a+c)/2, (b+c)/2, n-1);
out = [out1, out2, out3];
end
end
This creates a struct of length 3^n, each entry of which contains the coordinates of one of the small triangles in the sierpinski triangle. Your code to plot it might then look like
>> out = sierpinski([0,0], [1,0], [0.5, sqrt(3)/2], 8);
>> figure(); hold on;
>> for i = 1:length(out)
patch(out(i).xvals, out(i).yvals, 'k');
end
That crashes on my machine (it seems that Matlab doesn't handle thousands of patches on the same plot very well) but a similar loop which plots one point at the corner of each small triangle.
>> x = [out.xvals];
>> y = [out.yvals];
>> plot(x, y, '.');
which produces this plot
I don't have any code-examples ready, but:
Instead of drawing each triangle as a single patch-object, you could try drawing all triangles in one large patch.
Basically you'd only need to concatenate the x- and y-coordinates for each triangle separated by a NaN - this will prevent the patch from drawing lines connecting individual triangles.
E.g. the following line produces two separate triangles:
p = patch( [0 0.5 1 0 NaN 2 2.5 3 2 NaN ], [ 0 1 0 0 NaN 2 3 2 2 NaN], 'k')
Mind that, to have a closed triangle you need 4 points per triangle this way, the last point being identical to the first.
EDIT:
For each recursion level, you can 'erase' the central triangles, so you have to patch many fewer triangles. For example, at first level, you have three 'up' triangles and only one 'down' triangle. You can path this, instead of the other three.
a more compact routine is:
function sierpinski(rec)
[x, x0] = deal(cat(3, [1 0]', [-1 0]', [0 sqrt(3)]'));
for k = 1 : rec x = x(:,:) + x0 * 2 ^ k / 2;
end
patch('Faces', reshape(1 : 3 * 3 ^ k, 3, '')', 'Vertices', x(:,:)')
end
So you have to fill much less triangles if...
function sierpinski(rec)
close all
%Main Triangle
hFig=figure;
units=get(hFig,'units');
set(hFig,'units','normalized','outerposition',[0 0 1 1], 'Color', 'white');
set(hFig,'units',units); clear units
hold on
Vx=[0 0.5 1]; Vy=[0 realsqrt(3)/2 0];
fill(Vx,Vy,'b')
%the number of white triangles = sum(3.^(0:1:rec-1))
whitex=NaN(3,sum(3.^(0:1:rec-1))); whitey=whitex; K=1;
for S=1:rec
[Vx,Vy]=sierpinskisect;
end
fill(whitex,whitey,'w')
function [outX,outY]=sierpinskisect
%the number of blue triangles = 3^S
L=size(Vx,1);
outX=NaN(3*L,3); outY=outX; J=1;
for I=1:L
%left blue triangle
outX(J,:)=[Vx(I,1) mean(Vx(I,(1:2))) mean(Vx(I,([1 3])))];
outY(J,:)=[Vy(I,1) mean(Vy(I,(1:2))) mean(Vy(I,([1 3])))];
J=J+1;
%right blue triangle
outX(J,:)=[mean(Vx(I,([1 3]))) mean(Vx(I,(2:3))) Vx(I,3)];
outY(J,:)=[mean(Vy(I,([1 3]))) mean(Vy(I,(2:3))) Vy(I,3)];
J=J+1;
%upper blue triangle
outX(J,:)=[mean(Vx(I,(1:2))) Vx(I,2) mean(Vx(I,(2:3)))];
outY(J,:)=[mean(Vy(I,(1:2))) Vy(I,2) mean(Vy(I,(2:3)))];
J=J+1;
%white triangle
whitex(:,K)=[outX(J-3,2);outX(J-3,3);outX(J-2,2)];
whitey(:,K)=[outY(J-3,2);outY(J-3,3);outY(J-2,2)];
K=K+1;
end
end
end