Showing angles around plot in matlab / octave - matlab

I can create a plot with pol2cart but how can I get the angles to show up at the end off the lines? See code below:
hold on ;
for angle = 0:20:(360-20)
[x1,y1] = pol2cart( angle / 180 * pi , [0 2]);
plot(x1,y1,'r')
end
for rho = 0:0.1:2
[x1,y1] = pol2cart( 0:0.01:2*pi , rho);
plot(x1,y1,'b')
end
axis equal
I'm trying to get the angle increments to show up all around see image below.
Please note I didn't draw all the numbered angles just the first couple to show what I'm trying to do
PS: I'm using octave 3.8.1 which tries to use the same language syntax as matlab

You could do something like
step = 20;
r= 2.2;
for idx = 0:step:360-step
text(r*cos(pi*idx/180),r*sin(pi*idx/180),num2str(idx), ...
'HorizontalAlignment','center', 'color',[1 .5 0])
end
For a better fit, include
axis(1.05*[-r r -r r])
axis equal
(This works for MATLAB, I dont know if the syntax is exactly the same in Octave.)

Here's the information and plot animated
%polar_chart_with_angles and there opposites
clear all, clc, clf
%find how many angles to make one full cycleremeber to divide by two if using stereo signal 180 out of phase
incr=72;
angle_wanted=incr;
n = lcm(360, 180 - angle_wanted) / (180 - angle_wanted)
angle_div=[0:incr:incr*n] %angle divsions
angle_div_mod=mod(angle_div,360) %angle divsions mod into 360
angle_div_mod_opp=mod(angle_div+180,360) %oppsite angle divsions mod into 360
%for circles
r= 2.2;
for rho = 0:0.1:2
[x1,y1] = pol2cart( 0:0.01:2*pi , rho);
plot(x1,y1,'b')
axis(1.10*[-r r -r r])
axis equal
hold on;
end
%for orig angles
for ii=1:n
angle=angle_div(ii)
[x1,y1] = pol2cart( angle / 180 * pi , [0 2]);
plot(x1,y1,'r')
hold on;
title_h=title(['Norig= ', int2str(ii)]);
%title_h = title('This is the title');
set(title_h, 'Position', [0.5, 0.02],'VerticalAlignment', 'bottom', 'HorizontalAlignment', 'left')
%%for creating orig angles
idx=angle_div_mod(ii);
text(r*cos(pi*idx/180),r*sin(pi*idx/180),num2str(idx), 'HorizontalAlignment','center', 'color',[1 .5 0])
pause (.1)
end
%for oppsite angles
for ii=1:n
angle_opp=angle_div_mod_opp(ii)
[x1,y1] = pol2cart( angle_opp/ 180 * pi , [0 2]);
plot(x1,y1,'g')
hold on;
title(['Nopp= ', int2str(ii)]);
%for creating oppsite angles
idx=angle_div_mod_opp(ii);
text(r*cos(pi*idx/180),r*sin(pi*idx/180),num2str(idx), 'HorizontalAlignment','center', 'color',[.5 .7 .7])
pause (.1)
end

Related

Applying 3D rotation matrix to x, y, z values obtained from surface function

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)

Keep tracking the center of a ball with positional updates

In the code below, I am attempting to move a ball from 90 degrees to 44 degrees and back to 90 degrees. I wanted to be able to track the position of the ball's center point. I am trying to do this by plotting a marker that follows the ball. I would also like to keep seeing the (x,y) position of the ball being updated as the ball moves.
Can you help me modify my code so that:
1. The marker remains in the center of the ball, and
2. Keep displaying the (x,y) position of the marker (ball's center) as it moves?
Here is what I have done so far:
close all; clc; clear;
% Define position of arm
theta=0:10:360; %theta is spaced around a circle (0 to 360).
r=0.04; %The radius of our circle.
%Define a circular magenta patch.
x=r*cosd(theta) + 0.075;
y=r*sind(theta) + 1;
% Size figure and draw arms
figure('position', [800, 300, 600, 550]);
point = plot(0.075,1, 'bo', 'markers', 3);
hold on
myShape2=patch(x,y,'m');
set(myShape2,'Xdata',x,'Ydata',y);
axis([-1.5 3 -1 3]); grid on;
n = 1;
T=0.15; %Delay between images
for theta = pi/2:-pi/90:0,
if theta >= pi/4;
theta = theta;
else
theta = pi/2 - theta;
end
Arot = [sin(theta) cos(theta); -cos(theta) sin(theta)];
xyRot = Arot * [x; y]; % rotates the points by theta
xyTrans = xyRot;
point = plot(xyTrans(1, n),xyTrans(2, n), 'bo', 'markers', 3);
hold on;
set(myShape2,'Xdata',(xyTrans(1, :)),'Ydata',(xyTrans(2, :)));
pause(T); %Wait T seconds
end
Thanks for your time and help!
close all; clc; clear;
% Define position of arm
theta=0:10:360; %theta is spaced around a circle (0 to 360).
r=0.04; %The radius of our circle.
%Define a circular magenta patch.
x=r*cosd(theta) + 0.075;
y=r*sind(theta) + 1;
% Size figure and draw arms
figure('position', [800, 300, 600, 550]);
hold on
myShape2=patch(x,y,'m');
set(myShape2,'Xdata',x,'Ydata',y);
point = plot(0.075,1, 'bo', 'markers', 1);
dim = [.2 .5 .3 .3];
axis([-1.5 3 -1 3]); grid on;
T=0.15;
% Create annotation object to display object center
ano = annotation('textbox',dim,'String',['center position: (','0.075, 1'],'FitBoxToText','on');
for theta = pi/2:-pi/90:0,
if theta >= pi/4;
theta = theta;
else
theta = pi/2 - theta;
end
Arot = [sin(theta) cos(theta); -cos(theta) sin(theta)];
xyTrans = Arot * [x; y];
% Remove plot and annotation object from previous frame
delete(point)
delete(ano)
set(myShape2,'Xdata',(xyTrans(1, :)),'Ydata',(xyTrans(2, :)));
% Calculate the center of the patch as mean x and y position
x_pos = mean(xyTrans(1, :));
y_pos = mean(xyTrans(2, :));
point = plot(x_pos, y_pos, 'bo', 'markers', 1);
ano = annotation('textbox',dim,'String',['center position: (',sprintf('%0.3f', x_pos),', ',...
sprintf('%0.3f', y_pos),')'],'FitBoxToText','on');
axis([-1.5 3 -1 3]); grid on;
pause(T);
end

Plotting unit circles in matlab and using the hold on to insert individual data points and plotting the intersection with circle

I was trying to produce the following figure:
as similar as possible. I was having difficulties because I wasn't sure how to plot the unit circle. How does one do that? I tried using the polar function but I couldn't then make it also plot the blue crosses and red crosses. Anyone has an idea?
Edited answer
Here is a part of the code:
% --- Plot everything on the same axes
hold on
% --- Plot the unit circle:
theta = linspace(0, 2*pi, 360);
plot(cos(theta), sin(theta), 'k--');
% --- Plot the blue points
x = [0.2 0.4 0.4 0.8];
y = [0.4 0.2 0.8 0.4];
scatter(x, y, 'bs');
% --- Plot the red points:
x = [0.4 0.8];
y = [0.4 0.8];
scatter(x, y, 'ro');
There are still many modifications to do to get the final plots, but at least this is a starting point.
Second edit
To answer your question about the intersection of a line and a circle, you have to start with the maths behind. Line and circle are defined by the following equations:
y = a.x + b % Cartesian definition of a line
(x-x0)² + (y-y0)² = r² % Cartesian definition of a circle
If you combine the two, you realize that finding the intersection is similar to finding the solution of:
(a²+1).x² + 2(a(b-y0)-x0).x + x0²+(b-y0)²-r² = 0
i.e. the roots of a polynom. As this is a trinom, there are 3 possibilities: 0 solution (no intersection), 1 solution (line is tangent to the circle) and 2 solutions (line crossing the circle).
So, in practice you have to:
Get the parameters a, b, x0, y0 and r of your problem
Find the roots of the polynom (for instance, with the function roots)
Decide what to do based on the number of roots.
Hope this helps,
%% Construct polar grid (put inside another function)
range = 0.2:0.2:1;
n = 50;
for i=1:length(range)
ro = ones(1,n);
ro = ro.*range(i);
th = linspace(0,pi*2,n);
[xx,yy] = pol2cart(th,ro);
plot(xx,yy, 'color',[.9 .9 .9]), grid on, hold on
n = round(n * 1.5);
end
%% Plot like normal
x1 = [.2 .4 .4 .8];
y1 = [.4 .2 .8 .4];
x2 = [.4 .8];
y2 = [.4 .8];
plot(x1,y1, 'bx',...
x2,y2, 'ro');
xlim([-.05 1]);
ylim([-.05 1]);

Matlab rejection sampling points not displayed

I am using the following code for Pi approximation, using the rejection sampling method.
% DISPLAY A CIRCLE INSCRIBED IN A SQUARE
figure;
a = 0:.01:2*pi;
x = cos(a); y = sin(a);
hold on
plot(x,y,'k','Linewidth',2)
t = text(0.5, 0.05,'r');
l = line([0 1],[0 0],'Linewidth',2);
axis equal
box on
xlim([-1 1])
ylim([-1 1])
title('Unit Circle Inscribed in a Square')
pause;
rand('seed',12345)
randn('seed',12345)
delete(l); delete(t);
% DRAW SAMPLES FROM PROPOSAL DISTRIBUTION
samples = 2*rand(2,100000) - 1;
% REJECTION
reject = sum(samples.^2) > 1;
% DISPLAY REJECTION CRITERION
scatter(samples(1,~reject),samples(2,~reject),'b.')
scatter(samples(1,reject),samples(2,reject),'rx')
hold off
xlim([-1 1])
ylim([-1 1])
The expected result should be a blue circle inside of a red square. When I run the code the red point for building the square are displayed, but the blue point not.
The expected result should be as the picture found at this Link
But I get the following result:
Does anybody know what I can possibly do in order to visualize the blue points as well? Thanks in advance.
The scatter function is probably not the best choice for such huge number of points. Try this instead:
t = 0:.01:2*pi;
x = cos(t); y = sin(t);
samples = 2*rand(2,100000) - 1;
reject = sum(samples.^2) > 1;
props = {'LineStyle','none', 'Marker','.', 'MarkerSize',1};
line(x, y, 'Color','k', 'LineWidth',2)
line(samples(1,~reject), samples(2,~reject), props{:}, 'Color','b')
line(samples(1,reject), samples(2,reject), props{:}, 'Color','r')
axis equal; axis([-1 1 -1 1])
box on

Drawing shape context logpolar bins in MATLAB

I am using shape context histograms as a feature descriptor to encode silhouette images. To assist with debugging, I would like to view the shape context logpolar bins overlaid on a silhouette image (the sample points taken from the edge image).
An example of what it should look like for one of the points is as follows:
I know how to display the circles (radial bins), but I am having difficulty in producing the angular bins (lines).
Given a set of angles, how can I draw line segments similar to those shown in the example image?
You can use this function:
function scDrawPolar(samp,point,r_min,r_max,nbins_theta,nbins_r)
%SCDRAWPOLAR draw a polar on the center point
% point - the center point
% r_min - min radius
% r_max - max radius
% nbins_theta - theta divide
% nbins_r - r divide
% fig_handle - draw the diagram on which figure
gca;
hold on;
plot(samp(1,:)',samp(2,:)','r.');
plot(point(1),point(2),'ko');
r_bin_edges=logspace(log10(r_min),log10(r_max),nbins_r);
% draw circles
th = 0 : pi / 50 : 2 * pi;
xunit = cos(th);
yunit = sin(th);
for i=1:length(r_bin_edges)
line(xunit * r_bin_edges(i) + point(1), ...
yunit * r_bin_edges(i) + point(2), ...
'LineStyle', ':', 'Color', 'k', 'LineWidth', 1);
end
% draw spokes
th = (1:nbins_theta) * 2*pi / nbins_theta;
cs = [cos(th);zeros(1,size(th,2))];
sn = [sin(th);zeros(1,size(th,2))];
line(r_max*cs + point(1), r_max*sn + point(2),'LineStyle', ':', ...
'Color', 'k', 'LineWidth', 1);
axis equal;
axis off;
hold off;
end
See the result here:
Doing this:
>> figure
>> axes
>> hold on
>> radius = 1;
>> theta = 0:30:360;
>> for angle = theta
line([0 radius * cosd(angle)], [0 radius * sind(angle)]);
end
produces this: