Drawing multiple polygons in Matlab with no borders - matlab

I'm creating a figure with many polygons which can overlap in Matlab. I do not want borders on any of the shapes, only a translucent fill. I was able to get the first shape to obey this request using:
fill(xv,yv,'blue','FaceAlpha',0.1,'EdgeColor','None','LineStyle','none');hold on;
However, each subsequent shape which is drawn in the loop ignores this style, instead cycling through colored borders. I was able to use the set command to override the color cycle, but this still draws a border...I do not want any border. The border cannot be drawn at all because we are using the overlapping properties of the shapes, and the presence of any borders would perturb the nature of our simulation.
Here is the complete code:
for count = 1:92
x=randn*clustering;
y=randn*clustering;
angle=randn*360;
rectangle(width,height,x,y,angle);
end
function rectangle(w,h,x,y,angle)
%Define the rectangle
xv=[x x+w x+w x x];
yv=[y y y+h y+h y];
%Define the rotation transformation matrix
transform=[cos(angle) -sin(angle);sin(angle) cos(angle)];
%Define the translation to origin transform
xcenter=x+.5*w;
ycenter=y+.5*h;
%Perform translation to origin
tx=xv-xcenter;
ty=yv-ycenter;
%Perform rotation
rotated=transform*[tx;ty];
%Perform translation back to original location
xv=rotated(1,:)+xcenter;
yv=rotated(2,:)+ycenter;
%Plot result
figure(1);
plot(xv,yv);
fill(xv,yv,'blue','FaceAlpha',0.1);hold on;
axis square;
axis([-30 30 -30 30]);

Related

Plotting a 2D gaussian in MATLAB in one color but varaying levels of transparency

I want to plot 2D representation of a Gaussian wave function in MATLAB. I want the 2D plot to be in one color (green), which gets transparent away from the center of the Gaussian.
When I use imagesc (like in the next code) I get a Gaussian over a black square (as shown in the figure below).
I do not want the black backgrount, and I want the Gaussian to be in one color, but gets transparent away from the center, so that I won't get the black square, only green circle (over a white background) where the circle gets transparent away from its center.
How can I do that ???
close all;clc
figure
xlim_min=-4;
xlim_max=4;
ylim_min=-4;
ylim_max=4;
ylim([ylim_min ylim_max])
xlim([xlim_min xlim_max])
x=-1:0.001:1;
y=-1:0.001:1;
[X,Y]=meshgrid(x,y);
c1=10;
c1_new=c1*0.3;
x_offset=0;
y_offset=0;
w_function=0.5*0.25*exp(-c1_new*((X+x_offset).^2+...
(Y+y_offset).^2));
imagesc(x,y,w_function);
ylim([ylim_min ylim_max])
xlim([xlim_min xlim_max])
To obtain transparency, use the AlphaData and AlphaDataMapping properties of the image. In the following, I'm explicitly computing the transparency (alpha) as an affine function of the data values, in order to specify minimum and maximum transparency values; and I set AlphaDataMapping to none so those values are used without any modifications.
So, replace your line
imagesc(x,y,w_function);
by
min_alpha = .2; % desired minimum alpha
max_alpha = 1; % desired maximum alpha
alpha = min_alpha + (max_alpha-min_alpha)/max(w_function(:))*w_function; % compute alpha
imagesc(x,y,w_function,'AlphaData',alpha,'AlphaDataMapping','none'); % image with alpha
Note how the blue part is more transparent (smaller alpha) than the yellow part.
To have the color blend smoothly with the outer region, set a mininum alpha of 0 and define the function on a larger grid. You can also change the colormap if desired. Since the transparency already varies, you probably want constant color in the colormap.
close all;clc
figure
xlim_min=-4;
xlim_max=4;
ylim_min=-4;
ylim_max=4;
ylim([ylim_min ylim_max])
xlim([xlim_min xlim_max])
x=-2:0.001:2; % large enough that the function approximately ...
y=-2:0.001:2; % ... reaches 0 within this rectangle
[X,Y]=meshgrid(x,y);
c1=10;
c1_new=c1*0.3;
x_offset=0;
y_offset=0;
w_function=0.5*0.25*exp(-c1_new*((X+x_offset).^2+...
(Y+y_offset).^2));
min_alpha = 0; % desired minimum alpha: set to 0
max_alpha = 1; % desired maximum alpha
alpha = min_alpha + (max_alpha-min_alpha)/max(w_function(:))*w_function; % compute alpha
imagesc(x,y,w_function,'AlphaData',alpha,'AlphaDataMapping','none'); % image with alpha
cm = [0 .7 0]; % define colormap: single color, dark green
colormap(cm) % apply colormap
ylim([ylim_min ylim_max])
xlim([xlim_min xlim_max])

Matlab - rotate a card [duplicate]

This question already has answers here:
How to straighten a tilted square shape in an image?
(2 answers)
Closed 5 years ago.
I have a cropped image of a card:
The card is a rectangle with rounded corners, is brightly colored, and sits on a relatively dark background.
It is, therefore, easy to differentiate between pixels belonging to the card and pixels belonging to the background.
I want to use MATLAB to rotate the card so its sides are vertical and horizontal (and not diagonal) and create an image of nothing but the straightened card.
I need this to work for any reasonable card angle (say +45 to -45 degrees of initial card rotation).
What would be the best way of doing this?
Thanks!
You can do this by finding the lines made by the edges of the card. The angle of rotation is then the angle between one of the lines and the horizontal (or vertical).
In MATLAB, you can use the Hough line detector to find lines in a binary image.
0. Read the input image
I downloaded your image and renamed it card.png.
A = imread('card.png');
We don't need color information, so convert to grayscale.
I = rgb2gray(A);
1. Detect edges in the image
A simple way is to use the Canny edge detector. Adjust the threshold to reject noise and weak edges.
BW = edge(I, 'canny', 0.5);
Display the detected edges.
figure
imshow(BW)
title('Canny edges')
2. Use the Hough line detector
First, you need to use the Hough transform on the black and white image, with the hough function. Adjust the resolution so that you detect all lines you need later.
[H,T,R] = hough(BW, 'RhoResolution', 2);
Second, find the strongest lines in the image by finding peaks in the Hough transform with houghpeaks.
P = houghpeaks(H, 100); % detect a maximum of 100 lines
Third, detect lines with houghlines.
lines = houghlines(BW, T, R, P);
Display the detected lines to make sure you find at least one along the edge of the card. The white border around the black background in your image makes detecting the right edges a bit more difficult.
figure
imshow(A)
hold on
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1), xy(:,2), 'LineWidth', 2, 'Color', 'red');
end
title('Detected lines')
3. Calculate the angle of rotation
lines(3) is the left vertical edge of the card. lines(3).point2 is the end of the line that is at the bottom. We want this point to stay where it is, but we want to vector along the line to be aligned with the vector v = [0 -1]'. (The origin is the top-left corner of the image, x is horizontal to the right and y is vertical down.)
lines(3)
ans =
struct with fields:
point1: [179 50]
point2: [86 455]
theta: 13
rho: 184
Simply calculate the angle between the vector u = lines(3).point1 - lines(3).point2 and the vertical vector v.
u = lines(3).point1 - lines(3).point2; % vector along the vertical left edge.
v = [0 -1]; % vector along the vertical, oriented up.
theta = acos( u*v' / (norm(u) * norm(v)) );
The angle is in radians.
4. Rotate
The imrotate function lets you rotate an image by specifying an angle in degrees. You could also use imwarp with a rotation transform.
B = imrotate(A, theta * 180 / pi);
Display the rotated image.
figure
imshow(B)
title('Rotated image')
Then you would have to crop it.

Matlab - isolating x/y values of a circle within a circle

I am looking for a way to isolate the x and/or y coord of a circle within a circle, as shown in the image.
I need to isolate this so i can set a condition that when a ball enters a circle, i can change some qualities of the ball, i have been able to do this for the outer circle, which is centred at [0 0] using the code below,
while sqrt(XY(1)^2 + XY(2)^2) < 5
but cannot figure out how to do it for the interior circles.
Thanks
If you know the center and the radius of the inner circles you are able to calculate the X and Y coordinates of the circles then, you can use the inpolygon function to thest if a point is inside a circle (inpolygon returns 1 if a point is inside the polygon, 0 otherwise). In this case the polygon is constitued by the points of the circles.
In the following code a point moves across three circles (two of them placed inside the bigger one).
The inpolygon function is used to test if the point (the ball) is inside a circle and in change its colour according to the circle it is inside to.
% Define the radius and centre of three circles
r1=10;
r2=3
r3=4
c1=[0 0];
c2=[3 3];
c3=[-4 -4]
% Calculate the X and Y coord of the three circles
t=0:.01:2*pi;
x=cos(t)*r1
y=sin(t)*r1
x1=cos(t)*r2+c2(1)
y1=sin(t)*r2+c2(2)
x2=cos(t)*r3+c3(1)
y2=sin(t)*r3+c3(2)
% Plot the circles
plot(x,y,'r')
hold on
plot(x1,y1,'g')
plot(x2,y2,'b')
daspect([1 1 1])
% Define the ball trajectory
mx=-10:1:10;
my=-10:1:10;
for i=1:length(mx)
% Plot the ball: black if outside of all the circle
mh=plot(mx(i),my(i),'o','markerfacecolor','k','markeredgecolor','k')
% If the ballk is inside the first circle, make it red
if(inpolygon(mx(i),my(i),x,y))
mh.MarkerFaceColor='r';
mh.MarkerEdgeColor='r';
end
if(inpolygon(mx(i),my(i),x1,y1))
% If the ballk is inside the second circle, make it green
mh.MarkerFaceColor='g';
mh.MarkerEdgeColor='g';
end
if(inpolygon(mx(i),my(i),x2,y2))
% If the ballk is inside the third circle, make it blue
mh.MarkerFaceColor='b';
mh.MarkerEdgeColor='b';
end
pause(1)
end
Hope this helps.
Qapla'

Is there a way to control distortion in Matlab's 3D viewer?

The background of this problem relates to my attempt to combine output from a ray tracer with Matlab's 3d plotters. When doing ray tracing, there is no need to apply a perspective transformation to the rendered image. You see this in the image below. Basically, the intersections of the rays with the viewport will automatically adjust for the perspective scaling.
Suppose I've gone and created a ray-traced image (so I am given my camera, my focal length, viewport dimensions, etc.). How do I create exactly the same view in Matlab's 3d plotting environment?
Here is an example:
clear
close all
evec = [0 200 300]; % Camera position
recw = 200; % cm width of box
recl = 200; % cm length of box
h = 150; % cm height of box
% Create the front face rectangle
front = zeros(3,5);
front(:,1) = [-recw/2; 0; -recl/2];
front(:,2) = [recw/2; 0; -recl/2];
front(:,3) = [recw/2; h; -recl/2];
front(:,4) = [-recw/2; h; -recl/2];
front(:,5) = front(:,1);
% Back face rectangle
back = zeros(3,5);
back(:,1) = [-recw/2; 0; recl/2];
back(:,2) = [recw/2; 0; recl/2];
back(:,3) = [recw/2; h; recl/2];
back(:,4) = [-recw/2; h; recl/2];
back(:,5) = back(:,1);
% Plot the world view
figure(1);
patch(front(1,:), front(2,:), front(3,:), 'r'); hold all
patch(back(1,:), back(2,:), back(3,:), 'b');
plot3(evec(1), evec(2), evec(3), 'bo');
xlabel('x'); ylabel('y'); zlabel('z');
title('world view'); view([-30 40]);
% Plot the camera view
figure(2);
patch(front(1,:), front(2,:), front(3,:), 'r'); hold all
patch(back(1,:), back(2,:), back(3,:), 'b');
xlabel('x'); ylabel('y'); zlabel('z');
title('Camera view');
campos(evec);
camup([0 1 0]); % Up vector is y+
camproj('perspective');
camtarget([evec(1), evec(2), 0]);
title('camera view');
Now you see the world view
and the camera view
I know how to adjust the camera position, the camera view angle, and orientation to match the output from my ray tracer. However, I do not know how to adjust Matlab's built-in perspective command
camproj('perspective')
for different distortions.
Note: within the documentation, there is the viewmtx command, which allows you to output a transformation matrix corresponding to a perspective distortion of a certain angle. This is not quite what I want. I want to do things in 3D and through Matlab's OpenGL viewer. In essence, I want a command like
camproj('perspective', distortionamount)
so I can match up the amount of distortion in Matlab's viewer with the distortion from the ray tracer. If you use the viewmtx command to create the 2D projections, you will not be able to use patch' orsurf' and keep colours and faces intact.
The MATLAB perspective projection works just like your raytracer. You don't need any transformation matrices to it use it. Perspective distortion is determined entirely by the camera position and direction of projection.
In the terminology of the raytracer diagram above, if the CameraPosition matches your raytracer's pinhole coordinates and the vector between CameraPosition and CameraTarget is perpendicular to your raytracer's viewport, the perspective distortion will also match. The rest is just scaling and alignment.

MATLAB how to Draw a circle around a chosen node in a graph?

l have generated a topology of a network with 200 nodes.than l want to draw a circle with black color around a choosen node(satisfying a certain condition IF (condition) ).
to simplify let the user introduce the the index of the node to circle with the black color.
here is my code of the generated topology.l need to add wich instructions to draw the circle around the choosen node ?
X=100;
Y=100;
N=200; %number of nodes
nodesX(1)=rand*X;
nodesY(1)=rand*Y;
for i=2:N
nodesX(i)=rand*X;
nodesY(i)=rand*Y;
d(i-1) =((nodesX(i)-nodesX(i-1)).^2+(nodesY(i)-nodesY(i-1)).^2).^0.5;
while (d(i-1)>200)
nodesX(i)=rand*X;
nodesY(i)=rand*Y;
d(i-1) =((nodesX(i)-nodesX(i-1)).^2+(nodesY(i)-nodesY(i-1)).^2).^0.5;
end
end
h_old=plot(nodesX,nodesY,'m*');
labels=[1:N]';
labels=num2str(labels);
text(nodesX,nodesY,labels);
xlabel('X (Meters)');
ylabel('Y (Meters)');
title(['Network Topology with',num2str(N),'nodes']);
hold on
for k=1:N;
for j=1:N;
if (k~=j)
d=((nodesX(k)-nodesX(j))^2+(nodesY(k)-nodesY(j))^2)^0.5;
end
if (k~=j);
if(d < 50);
line([nodesX(k),nodesX(j)],[nodesY(k),nodesY(j)]);
end
end
end;
end;
Split it into two tasks:
Task 1:
Define a simple function to draw a circle. A cheap and dirty way is to use polar expressions.
function [] = circle(center_x,center_y,r)
theta = 0:0.01:2*pi;
x = center_x + r*cos(theta);
y = center_y + r*sin(theta);
plot(x,y,'k','LineWidth',2)
Task 2:
Pass this function the NodeX and NodeY values of the indexed node as the point at which the circle is centered. You can set the radius of the circle as per your choice. Using r=1 and picking an arbitrary index, I got:
Just one caveat: Make sure your axis are square. Otherwise, a circle might look like an ellipse. If you want to draw a circle around non-square axis, then you can modify the code to generate an ellipse instead.