I've been working on a project involving inverse source problem known within the electromagnetic wave field. The problem i have is that ; I have to define 3 points in a 2D space. These points should have a x,y coordinate of course and a value which will define its' current. Like this:
A1(2,3)=1
A2(2,-2)=2
and so on.
Also i have to define a circle around this and divide it into 200 points. Like the first point would be ; say R=2 ; B1(2,0) ;B50(0,2);B100(-2,0) and so on.
Now i really am having a hard time to define a space in MATLAB and circle it. So what i am asking is to help me define a 2D space and do it as the way i described. Thanks for any help guys!
This kind of code may be use. Look at grid in the Variable editor.
grid = zeros(50, 50);
R = 10;
angles = (1:200)/2/pi;
x = cos(angles)*R;
y = sin(angles)*R;
center = [25 20];
for n=1:length(angles)
grid(center(1)+1+round(x(n)), center(2)+1+round(y(n))) = 1;
end
You have to define a grid large enough for your need.
Here is a complete example that might be of help:
%# points
num = 3;
P = [2 3; 2 -2; -1 1]; %# 2D points coords
R = [2.5 3 3]; %# radii of circles around points
%# compute circle points
theta = linspace(0,2*pi,20)'; %'
unitCircle = [cos(theta) sin(theta)];
C = zeros(numel(theta),2,num);
for i=1:num
C(:,:,i) = bsxfun(#plus, R(i).*unitCircle, P(i,:));
end
%# prepare plot
xlims = [-6 6]; ylims = [-6 6];
line([xlims nan 0 0],[0 0 nan ylims], ...
'LineWidth',2, 'Color',[.2 .2 .2])
axis square, grid on
set(gca, 'XLim',xlims, 'YLim',ylims, ...
'XTick',xlims(1):xlims(2), 'YTick',xlims(1):xlims(2))
title('Cartesian Coordinate System')
xlabel('x-coords'), ylabel('y-coords')
hold on
%# plot centers
plot(P(:,1), P(:,2), ...
'LineStyle','none', 'Marker','o', 'Color','m')
str = num2str((1:num)','A%d'); %'
text(P(:,1), P(:,2), , str, ...
'HorizontalAlignment','left', 'VerticalAlignment','bottom')
%# plot circles
clr = lines(num);
h = zeros(num,1);
for i=1:num
h(i) = plot(C(:,1,i), C(:,2,i), ...
'LineStyle','-', 'Marker','.', 'Color',clr(i,:));
end
str = num2str((1:num)','Circle %d'); %'
legend(h, str, 'Location','SW')
hold off
Related
I am trying to plot a circle's equation-regression on x and y, but I do not know how to proceed. Any suggestions? (I want a circle to connect the points thru least square solution)
x = [5; 4; -1; 1];
y = [3; 5; 2; 1];
% circle's equation: x^2+y^2 = 2xc1+2yc2+c3
a = [2.*x,2.*y,ones(n,3)]
b = [x.^2 + y.^2];
c = a\b;
How do I plot the circle after this
There are a couple of ways how to plot a circle in matlab:
plot a line where the data points form a circle
use the 'o' marker in plot and the 'MarkerSize' name-value pair to set the radius of the circle
you can plot a circle image using the vscircle function
In your case, I would go with the first option, since you maintain in control of the circle size.
use the rectangle(...,'Curvature',[1 1]) function [EDITED: thx to #Cris Luengo]
So here is a plotting function
function circle(x,y,r)
%x and y are the coordinates of the center of the circle
%r is the radius of the circle
%0.01 is the angle step, bigger values will draw the circle faster but
%you might notice imperfections (not very smooth)
ang=0:0.01:2*pi+.01;
xp=r*cos(ang);
yp=r*sin(ang);
plot(x+xp,y+yp);
end
So with your (corrected) code, it looks like this
x = [5; 4; -1; 1];
y = [3; 5; 2; 1];
% circle's equation: x^2+y^2 = 2xc1+2yc2+c3
a = [2.*x,2.*y,ones(length(x),1)];
b = [x.^2 + y.^2];
c = a\b;
x_m = c(1)/2;
y_m = c(2)/2;
r = sqrt(x_m^2 + y_m^2 -c(3));
% plot data points
plot(x,y,'o')
hold on
% plot center
plot(x_m,y_m,'+')
% plot circle
circle(x_m,y_m,r)
hold off
Applying 3D rotation matrix to the x,y,z values obtained from surface function object. The error I get is due to the matrix not being nonconforment but how can I adjust the matrix correctly?
I know hgtransform / makehgtform can do rotations but I need to use rotation matrices since I plan on testing it using matrices created from quaternions.
I've created a little plane out of cylinders and the surface functions.
See code below:
clear all,clf
ax=axes('XLim',[-2 2],'YLim', [-2 10],'ZLim',[-1.5 1.5]);
grid on;
%axis equal;
xlabel('x');
ylabel('y');
zlabel('z');
ax
% rotate around
rot_mat = [.707 -.707 0;.707 .707 0; 0 0 1] %rotation matrix
[xc yc zc] = cylinder([0.1 0.0]); %cone
[x y z]= cylinder([0.2 0.2]);
h(1) = surface(xc,zc,-yc,'FaceColor', 'red'); %noise cone
h(2) = surface(z,y,0.5*x,'FaceColor', 'blue'); %right wing
h(3) = surface(-z,y,0.5*x,'FaceColor', 'yellow');%left wing
h(4) = surface(x,-1.5*z,0.5*y,'FaceColor', 'green'); %main body
h(5) = surface(xc,(1.5*yc)-1.3,z*.5,'FaceColor', 'red'); %tail
view(3);
x_temp = get(h(1),'xdata'); % get x values
y_temp = get(h(1),'ydata');
z_temp =get(h(1),'zdata');
xc_new=x_temp.*rot_mat;
%zc_new=
%yc_new=
I can get the x,y, and z value by using the commands
x_temp = get(h(1),'xdata');
y_temp = get(h(1),'ydata');
z_temp = get(h(1),'zdata');
The error I get is due to the matrix being nonconforment but how can I adjust the matrix correctly?
error: test_object_matrix_rot: product: nonconformant arguments (op1 is 2x21, op2 is 3x3).
The error is with the line xc_new=x_temp.*rot_mat;
PS: I'm using Octave 5.0.91 which is like Matlab
YOu are messing up a lot of things......in fact I would say, you have made your work complex. YOu should straight away work on matrices to rotate to new positons instead of arrays and picking them from the figure.
This line:
x_temp = get(h(1),'xdata'); % get x values
giving you a 2*21 array and your rot_mat is 3X3.....you cannot multiply them. YOu need to pick (x,y,z) and multiply this point with rotation matrix to get the point shifted. Check the below pseudo code.....yo can develop your logic with the below example code.
t = 0:0.1:1;
[X,Y,Z] = cylinder((t));
%% Rotation
th = pi/2 ;
Rx = [1 0 0 ; 0 cos(th) -sin(th) ; 0 sin(th) cos(th)] ;
P0 = [X(:) Y(:) Z(:)] ;
P1 = P0*Rx ;
X1 = reshape(P1(:,1),size(X)) ;
Y1 = reshape(P1(:,2),size(X)) ;
Z1 = reshape(P1(:,3),size(X)) ;
figure
hold on
surf(X,Y,Z)
surf(X1,Y1,Z1)
view(3)
The below code plots circles in Matlab. How can I specify the MarkerEdgeColor and MarkerFaceColor in it.
function plot_model
exit_agents=csvread('C:\Users\sony\Desktop\latest_mixed_crowds\December\exit_agents.csv');
%scatter(exit_agents(:,2),exit_agents(:,3),pi*.25^2,'filled');
for ii =1:size(exit_agents,1),
circle(exit_agents(ii,2),exit_agents(ii,3),0.25);
end
end
function h = circle(x,y,r)
hold on
th = 0:pi/50:2*pi;
xunit = r * cos(th) + x;
yunit = r * sin(th) + y;
h = plot(xunit, yunit);
hold off
end
Using plot and scatter scales them weirdly when zooming. This is not what I wish for.
There are various options to plot circles. The easiest is, to actually plot a filled rectangle with full curvature:
%// radius
r = 2;
%// center
c = [3 3];
pos = [c-r 2*r 2*r];
r = rectangle('Position',pos,'Curvature',[1 1], 'FaceColor', 'red', 'Edgecolor','none')
axis equal
With the update of the graphics engine with R2014b this is really smooth:
If you have an older version of Matlab than R2014b, you will need to stick with your trigonometric approach, but use fill to get it filled:
%// radius
r = 2;
%// center
c = [3 3];
%// number of points
n = 1000;
%// running variable
t = linspace(0,2*pi,n);
x = c(1) + r*sin(t);
y = c(2) + r*cos(t);
%// draw filled polygon
fill(x,y,[1,1,1],'FaceColor','red','EdgeColor','none')
axis equal
The "resolution" can be freely scaled by the number of points n.
Your function could then look like
function h = circle(x,y,r,MarkerFaceColor,MarkerEdgeColor)
hold on
c = [x y];
pos = [c-r 2*r 2*r];
r = rectangle('Position',pos,'Curvature',[1 1], ...
'FaceColor', MarkerFaceColor, 'Edgecolor',MarkerEdgeColor)
hold off
end
I have an image (200x200) and want to find the neighborhood locations in a specific point with a predefined radius. For example, with the radius of 5, I have 25 points around a point. Does MATLAB can do it? The problem is about the edge of image which it does not always 25 points and the program should just find the points that are within that radius. These points can be varied from 1 (corner) to 25 (center of image)
Here is an example:
%# sample grayscale image
img = imread('cameraman.tif');
[imgH,imgW,~] = size(img);
%# circle params
t = linspace(0, 2*pi, 50); %# approximate circle with 50 points
r = 80; %# radius
c = [100 130]; %# center
%# get circular mask
BW = poly2mask(r*cos(t)+c(1), r*sin(t)+c(2), imgH, imgW);
%# show cropped image
imshow( immultiply(img,BW) )
axis on
This will handle edges cases just fine. The advantage of using POLY2MASK is that it computes the mask with a sub-pixel accuracy (read the algorithm section in the function documentation), provided you are using enough points to approximate the circle.
Following the discussion in the comments, I am adding another solution. For a given point, we compute the neighboring points within a specified number of steps (radius if you will). This is shown for both the 2D and the 3D case.
2D matrix
siz = [10 15]; %# matrix size
p = [5 10]; %# 2D point location
%# neighboring points
k = 2; %# radius size
[sx,sy] = ndgrid(-k:k,-k:k); %# steps to get to neighbors
xy = bsxfun(#plus, p, [sx(:) sy(:)]); %# add shift
xy = bsxfun(#min, max(xy,1), siz); %# clamp coordinates within range
xy = unique(xy,'rows'); %# remove duplicates
xy(ismember(xy,p,'rows'),:) = []; %# remove point itself
%# show solution
figure
line(p(1), p(2), 'Color','r', ...
'LineStyle','none', 'Marker','.', 'MarkerSize',50)
line(xy(:,1), xy(:,2), 'Color','b', ...
'LineStyle','none', 'Marker','.', 'MarkerSize',20)
grid on, box on, axis equal
axis([1 siz(1) 1 siz(2)])
xlabel x, ylabel y
3D matrix
siz = [10 15 8]; %# matrix size
p = [5 10 4]; %# 3D point location
%# neighboring points
k = 2; %# radius size
[sx,sy,sz] = ndgrid(-k:k,-k:k,-k:k); %# steps to get to neighbors
xyz = bsxfun(#plus, p, [sx(:) sy(:) sz(:)]); %# add shift
xyz = bsxfun(#min, max(xyz,1), siz); %# clamp coordinates within range
xyz = unique(xyz,'rows'); %# remove duplicates
xyz(ismember(xyz,p,'rows'),:) = []; %# remove point itself
%# show solution
figure
line(p(1), p(2), p(3), 'Color','r', ...
'LineStyle','none', 'Marker','.', 'MarkerSize',50)
line(xyz(:,1), xyz(:,2), xyz(:,3), 'Color','b', ...
'LineStyle','none', 'Marker','.', 'MarkerSize',20)
view(3), grid on, box on, axis equal
axis([1 siz(1) 1 siz(2) 1 siz(3)])
xlabel x, ylabel y, zlabel z
HTH
I have a set of 3 datasets which I want to plot in MATLAB, but the 'x' axis, I want to give in the form of a circle instead of of straight bottom line. Any idea on how to do it?
An example plot:
The normal command for plotting in MATLAB is plot(x, data1, x data2, x, data3), in that the x axis is taken as the straight line. I want the x axis taken as a circle. Does anyone know the command for it please.
#Alok asks if you want a polar plot. I tell you that you do want a polar plot ! See the Matlab documentation for the function polar() and its relations, such as cart2pol. Depending on your exact requirements (I haven't followed your link) you may find it relatively easy or quite difficult to produce exactly the plot you want.
The following is a complete example to show how to map the data from a line axis to a circle.
I show two ways of achieving the goal:
one where the three data series are overlapping (i.e all mapped to the same range)
the other option is to draw them superimposed (on different adjacent ranges)
The basic idea: if you have a series D, then map the points to a circle where the radius is equal to the values of the data using:
theta = linspace(0, 2*pi, N); %# divide circle by N points (length of data)
r = data; %# radius
x = r.*cos(theta); %# x-coordinate
y = r.*sin(theta); %# y-coordinate
plot(x, y, '-');
Option 1
%# some random data
K = 3;
N = 30;
data = zeros(K,N);
data(1,:) = 0.2*randn(1,N) + 1;
data(2,:) = 0.2*randn(1,N) + 2;
data(3,:) = 0.2*randn(1,N) + 3;
center = [0 0]; %# center (shift)
radius = [data data(:,1)]; %# added first to last to create closed loop
radius = normalize(radius',1)'+1; %# normalize data to [0,1] range
figure, hold on
%# draw outer circle
theta = linspace(5*pi/2, pi/2, 500)'; %# 'angles
r = max(radius(:)); %# radius
x = r*cos(theta)+center(1);
y = r*sin(theta)+center(2);
plot(x, y, 'k:');
%# draw mid-circles
theta = linspace(5*pi/2, pi/2, 500)'; %# 'angles
num = 5; %# number of circles
rr = linspace(0,2,num+2); %# radiuses
for k=1:num
r = rr(k+1);
x = r*cos(theta)+center(1);
y = r*sin(theta)+center(2);
plot(x, y, 'k:');
end
%# draw labels
theta = linspace(5*pi/2, pi/2, N+1)'; %# 'angles
theta(end) = [];
r = max(radius(:));
r = r + r*0.2; %# shift to outside a bit
x = r*cos(theta)+center(1);
y = r*sin(theta)+center(2);
str = strcat(num2str((1:N)','%d'),{}); %# 'labels
text(x, y, str, 'FontWeight','Bold');
%# draw the actual series
theta = linspace(5*pi/2, pi/2, N+1);
x = bsxfun(#times, radius, cos(theta)+center(1))';
y = bsxfun(#times, radius, sin(theta)+center(2))';
h = zeros(1,K);
clr = hsv(K);
for k=1:K
h(k) = plot(x(:,k), y(:,k), '.-', 'Color', clr(k,:), 'LineWidth', 2);
end
%# legend and fix axes
legend(h, {'M1' 'M2' 'M3'}, 'location', 'SouthOutside', 'orientation','horizontal')
hold off
axis equal, axis([-1 1 -1 1] * r), axis off
Option 2
%# some random data
K = 3;
N = 30;
data = zeros(K,N);
data(1,:) = 0.2*randn(1,N) + 1;
data(2,:) = 0.2*randn(1,N) + 2;
data(3,:) = 0.2*randn(1,N) + 3;
center = [0 0]; %# center (shift)
radius = [data data(:,1)]; %# added first to last to create closed loop
radius = normalize(radius',1)'; %# normalize data to [0,1] range
radius = bsxfun( #plus, radius, (1:2:2*K)' ); %# 'make serieson seperate ranges by addition
figure, hold on
%# draw outer circle
theta = linspace(5*pi/2, pi/2, 500)'; %# 'angles
r = max(radius(:))+1; %# radius
x = r*cos(theta)+center(1);
y = r*sin(theta)+center(2);
plot(x, y, 'k:');
%# draw mid-circles
theta = linspace(5*pi/2, pi/2, 500)'; %# 'angles
r = 1.5; %# radius
for k=1:K
x = r*cos(theta)+center(1);
y = r*sin(theta)+center(2);
plot(x, y, 'k:');
r=r+2; %# increment radius for next circle
end
%# draw labels
theta = linspace(5*pi/2, pi/2, N+1)'; %# 'angles
theta(end) = [];
r = max(radius(:))+1;
r = r + r*0.2; %# shift to outside a bit
x = r*cos(theta)+center(1);
y = r*sin(theta)+center(2);
str = strcat(num2str((1:N)','%d'),{}); %# 'labels
text(x, y, str, 'FontWeight','Bold');
%# draw the actual series
theta = linspace(5*pi/2, pi/2, N+1);
x = bsxfun(#times, radius, cos(theta)+center(1))';
y = bsxfun(#times, radius, sin(theta)+center(2))';
h = zeros(1,K);
clr = hsv(K);
for k=1:K
h(k) = plot(x(:,k), y(:,k), '.-', 'Color', clr(k,:), 'LineWidth', 2);
end
%# legend and fix axes
legend(h, {'M1' 'M2' 'M3'}, 'location', 'SouthOutside', 'orientation','horizontal')
hold off
axis equal, axis([-1 1 -1 1] * r), axis off
I should mention that normalize() is a custom function, it simply performs minmax normalization ((x-min)/(max-min)) defined as:
function newData = normalize(data, type)
[numInst numDim] = size(data);
e = ones(numInst, 1);
minimum = min(data);
maximum = max(data);
range = (maximum - minimum);
if type == 1
%# minmax normalization: (x-min)/(max-min) => x in [0,1]
newData = (data - e*minimum) ./ ( e*(range+(range==0)) );
end
%# (...)
end
You can find here all available MATLAB 2-D and 3-D plot functions.
Sorry, if it may be not a proper answer to your question (you already have plenty). I recently found very powerful tool to plot on circle - CIRCOS: http://mkweb.bcgsc.ca/circos/
Have a look, figures are really amazing. It's not Matlab-based, but Perl, and it's free. May be you will find it useful.