Create Circle In 3-D Axes - matlab

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`

Related

Animating circles, based on ODE-solver output in Matlab [duplicate]

I have a ball with these two equations:
x(t) = v0*cos(α)*t and
y(t) = h + v0*sin(α)*t− 1/2 gt^2 , where t ∈ [0,t final] is the time variable, h is the height, v0 is the initial speed, α is the angle made by v0 with the horizontal, g = 9.8 m/s^2. The floor is at y(x) = 0.
I need to draw a small animation of the ball moving on the plot. I now I should use for, plot, drawnow, but I don't know how to do it.
Can you tell me how to obain this animation?
First, here are some test variables to start with, including the acceleration due to gravity:
g = 9.8; %// m/s^2
v0 = 2; %// m/s
alpha = pi/6; %// Radians
h = 30; %// Start at 30 metres
t_final = 4.5; %// Seconds
t_vector = 0 : 0.01 : t_final;
t_vector in the last line of code creates a vector of points from the initial time of t = 0 up until our ending time in steps of 0.01. With these defined, our job is to go through each of these points in our vector and plot our ball. Next, let's create anonymous functions for each x and y to make our plotting easier:
x = #(t) v0*cos(alpha)*t;
y = #(t) h + v0*sin(alpha)*t - 0.5*g*t.^2;
What you can do next is use a for loop and go through each value of t_vector up until t_final and plot the individual point. You should probably make the point big so we can actually see what the ball looks like:
close all;
figure; hold on;
for t = t_vector
plot(x(t), y(t), 'b.', 'MarkerSize', 16);
axis([0 t_final 0 h]);
pause(0.01);
end
The above code will first close any figures we have open, spawn a new figure and use hold on so that we can call plot multiple times and append points to the graph without it erasing each time. Then, for each point in time, we plot the location on the graph as a blue dot, then make the size of the dot 16. We also make sure that the axis doesn't automatically adjust itself by enforcing that the x values are restricted between t = 0 up to t = t_final. We also restrict the y values from y = 0 up to the initial starting height, which is 30 in my example. At each point, we pause by 0.01 ms so you can see the drawing of the points.
As a bonus, this is what the figure looks like as an animated gif:

Saving two fig that can be superposed_ Matlab

I am saving two matlab figures as png and I want them to have the same size in order to be perfectly superposable.
The first figure is computed by the function 'FilledCircle2' which is a circle divided in half with two colors.
The second figure is computed by function 'FilledCircleL' which is the left half of the circle computed by the function 'FilledCircle2'.
I want to be able to have two figures, both with the same size so they can be perfectly superposed.
Can someone help me understand what I am doing wrong?
Here is my code, with both of the functions and respective outputs:
function []=FilledCircle2(x0,y0,Radius,N, col1, col2)
if(N<=1)
error('N must be greater than 1');
end
hold on
axis equal
axis off
hold on
t=(0:N)*2*pi/N; %t=-pi:0.01:pi
x=Radius*cos(t)+x0;
y=Radius*sin(t)+y0;
plot(x,y)
hold on
%Divide circle in to 2 equal parts
n=2;
thetas = linspace(-pi, pi,n+1); %linspace generates n points. The space between the points is [(pi/2)-(-pi/2)]/(n)
% Specify any colors wanted
colors = [col1; col2];
for k = 1:n
tt = linspace(thetas(k), thetas(k+1));
xi = Radius * cos(tt) + x0;
yi = Radius * sin(tt) + y0;
c2= fill([xi(:); x0], [yi(:); y0], colors(k,:)); %Assign diffrent colors to each circle 'slice'
set (c2, 'edgecolor','white')
set(c2,'LineWidth',2.0)
set(gcf,'PaperUnits','inches','PaperSize',[0.8666,0.8666],'PaperPosition',[0 0 0.8666 0.8666])%setting size (130/150, 130/150, 150pixels per inch being the default size of img), paper position is imporrtant as otherwise i will have extra border
set(gca, 'Position', [0 0 1 1]);
set(gcf,'color',[0.49019607843137 0.49019607843137 0.49019607843137])%figure properties, rgb(125/255,125/255,125/255)
fig = gcf;
fig.InvertHardcopy = 'off'; %saves the fig with the set background color
%rotates the plot
az= 90; %azimuth, az, is the horizontal rotation about the z axis as measured in degrees from the negative y-axis. Positive values indicate counterclockwise rotation
el= 90; % vertical elevation of the view point in degrees
view(az,el);
hold on
end
Here is the output of the function FilledCircle2(0,0,10,300, 'y', 'r'):
[
function []=HalfFilledCircleL(x0,y0,Radius,N, col1)
if(N<=1)
error('N must be greater than 1');
end
hold on
axis equal
% axis tight
axis off
hold on
t=(0:N)*(-pi)/N; %t=-pi:0.01:pi
x=Radius*cos(t)+x0;
y=Radius*sin(t)+y0;
hold on
c1=fill(x,y,col1); %filling the semi-circle
set (c1, 'edgecolor','white') %setting the outline color of the semi-circle
set(gcf,'color',[0.49019607843137 0.49019607843137 0.49019607843137])%figure properties, rgb(125/255,125/255,125/255)
set(c1,'LineWidth',2.0)
set(gcf,'PaperUnits','inches','PaperSize',[0.8666,0.8666],'PaperPosition',[0 0 0.8666,0.8666])%setting size (130/150, 130/150, 150pixels per inch being the default size of img), paper position is imporrtant as otherwise i will have extra border
set(gca, 'Position', [0 0 1 1]);
fig = gcf;
fig.InvertHardcopy = 'off'; %saves the fig with the set background color
% %rotates the plot
az= 90; %azimuth, az, is the horizontal rotation about the z axis as measured in degrees from the negative y-axis. Positive values indicate counterclockwise rotation
el= 90; % vertical elevation of the view point in degrees
view(az,el);
end
Here is the output of the function HalfFilledCircleL(0,0,10,300, 'r'):
use xlim and ylim to set the xy limits of the axes:
figure;
HalfFilledCircleL(0,0,10,300, 'r');
xlim([-12 12]);ylim([-12 12]);
az= -90; %azimuth, az, is the horizontal rotation about the z axis as measured in degrees from the negative y-axis. Positive values indicate counterclockwise rotation
el= 90; % vertical elevation of the view point in degrees
view(az,el);
figure;
FilledCircle2(0,0,10,300, 'y', 'r');
xlim([-12 12]);ylim([-12 12]);

Animating a ball in Matlab

I have a ball with these two equations:
x(t) = v0*cos(α)*t and
y(t) = h + v0*sin(α)*t− 1/2 gt^2 , where t ∈ [0,t final] is the time variable, h is the height, v0 is the initial speed, α is the angle made by v0 with the horizontal, g = 9.8 m/s^2. The floor is at y(x) = 0.
I need to draw a small animation of the ball moving on the plot. I now I should use for, plot, drawnow, but I don't know how to do it.
Can you tell me how to obain this animation?
First, here are some test variables to start with, including the acceleration due to gravity:
g = 9.8; %// m/s^2
v0 = 2; %// m/s
alpha = pi/6; %// Radians
h = 30; %// Start at 30 metres
t_final = 4.5; %// Seconds
t_vector = 0 : 0.01 : t_final;
t_vector in the last line of code creates a vector of points from the initial time of t = 0 up until our ending time in steps of 0.01. With these defined, our job is to go through each of these points in our vector and plot our ball. Next, let's create anonymous functions for each x and y to make our plotting easier:
x = #(t) v0*cos(alpha)*t;
y = #(t) h + v0*sin(alpha)*t - 0.5*g*t.^2;
What you can do next is use a for loop and go through each value of t_vector up until t_final and plot the individual point. You should probably make the point big so we can actually see what the ball looks like:
close all;
figure; hold on;
for t = t_vector
plot(x(t), y(t), 'b.', 'MarkerSize', 16);
axis([0 t_final 0 h]);
pause(0.01);
end
The above code will first close any figures we have open, spawn a new figure and use hold on so that we can call plot multiple times and append points to the graph without it erasing each time. Then, for each point in time, we plot the location on the graph as a blue dot, then make the size of the dot 16. We also make sure that the axis doesn't automatically adjust itself by enforcing that the x values are restricted between t = 0 up to t = t_final. We also restrict the y values from y = 0 up to the initial starting height, which is 30 in my example. At each point, we pause by 0.01 ms so you can see the drawing of the points.
As a bonus, this is what the figure looks like as an animated gif:

Shade a subset of a sphere's surface in MATLAB

I'm attempting to generate a plot of a hemisphere with a shaded area on the surface bound by max/min values of elevation and azimuth. Essentially I'm trying to reproduce this:
Generating the hemisphere is easy enough, but past that I'm stumped. Any ideas?
Here's the code I used to generate this sphere:
[x,y,z] = sphere;
x = x(11:end,:);
y = y(11:end,:);
z = z(11:end,:);
r = 90;
surf(r.*x,r.*y,r.*z,'FaceColor','yellow','FaceAlpha',0.5);
axis equal;
If you want to highlight a certain area of your hemisphere, first you decide the minimum and maximum azimuth (horizontal sweep) and elevation (vertical sweep) angles. Once you do this, take your x,y,z co-ordinates and convert them into their corresponding angles in spherical co-ordinates. Once you do that, you can then subset your x,y,z co-ordinates based on these angles. To convert from Cartesian to spherical, you would thus do:
Source: Wikipedia
theta is your elevation while phi is your azimuth. r would be the radius of the sphere. Because sphere generates co-ordinates for a unit sphere, r = 1. Therefore, to calculate the angles, we simply need to do:
theta = acosd(z);
phi = atan2d(y, x);
Take note that the elevation / theta is restricted 0 to 180 degrees, while the azimuth / phi is restricted between -180 to 180 degrees. Because you're only creating half of a sphere, the elevation should simply vary from 0 to 90 degrees. Also note that acosd and atan2d return the result in degrees. Now that we're here, you just have to subset what part of the sphere you want to draw. For example, let's say we wanted to restrict the sphere such that the min. and max. azimuth span from -90 to 90 degrees while the elevation only spans from 0 to 45 degrees. As such, let's find those x,y,z co-ordinates that satisfy these constraints, and ensure that anything outside of this range is set to NaN so that these points aren't drawn on the sphere. As such:
%// Change your ranges here
minAzimuth = -90;
maxAzimuth = 90;
minElevation = 0;
maxElevation = 45;
%// Compute angles - assuming that you have already run the code for sphere
%// [x,y,z] = sphere;
%// x = x(11:end,:);
%// y = y(11:end,:);
%// z = z(11:end,:);
theta = acosd(z);
phi = atan2d(y, x);
%%%%%// Begin highlighting logic
ind = (phi >= minAzimuth & phi <= maxAzimuth) & ...
(theta >= minElevation & theta <= maxElevation); % // Find those indices
x2 = x; y2 = y; z2 = z; %// Make a copy of the sphere co-ordinates
x2(~ind) = NaN; y2(~ind) = NaN; z2(~ind) = NaN; %// Set those out of bounds to NaN
%%%%%// Draw our original sphere and then the region we want on top
r = 90;
surf(r.*x,r.*y,r.*z,'FaceColor','white','FaceAlpha',0.5); %// Base sphere
hold on;
surf(r.*x2,r.*y2,r.*z2,'FaceColor','red'); %// Highlighted portion
axis equal;
view(40,40); %// Adjust viewing angle for better view
... and this is what I get:
I've made the code modular so that all you have to do is change the four variables that are defined at the beginning of the code, and the output will highlight that desired part of the hemisphere that are bounded by those min and max ranges.
Hope this helps!
One option is to create an array with the corresponding color you want to attribute to each point.
A minimal example (use trigonometry to convert your azimuth and elevation to logical conditions on x, y, and z):
c=(y>0).*(x>0).*(z>0.1).*(z<0.5);
c(c==0)=NaN;
surf(r.*x,r.*y,r.*z,c ,'FaceAlpha',0.5); axis equal;
yields this:
Note: this only works with the resolution of the grid. (i.e each 'patch' of the surface can have a different color). To exactly reproduce your plot, you might want to superpose the grid sphere with another one that has a much larger number of grid points on which you apply the above code.

How to search the location of a plotted dot in a zone in a plot

I am trying to figure out how to have matlab "search" for center points in my 10 x 10 plot which coordinates are linked to a 10 x 10 matrix. I have a randomly generated 10 x 10 matrix of "0"s and"1"s and each element is mapped to a an X coordinate and Y coordinate in the plot so wherever there is a "1" in my matrix, I am plotting a star in the plot. My question is I want to search through each cell in the grid from (100, 100) all the way to (1900,1900)that I am plotting and if there is a "star" plotted, I want to search to see if there is anymore "stars" being plotted behind this star in a rectangular zone say, 400 x 2000, and find their coordinates. The reason for the (100,100) to (1900, 1900) location is because each cell I am plotting is 200 x 200 and I am plotting the star in the middle of each cell. Here is the code I have to see what the plot looks like
clear all
close all
clc
xmin = 100;
xmax = 1900;
ymin = 100;
ymax = 1900;
n=10;
v=randi([0,1],n);
[vx,vy] = find(v);
x = linspace(xmin,ymax,n);
y = linspace(ymin,ymax,n);
vx = x(vx);
vy = y(vy);
scatter(vx,vy, '*');
axis([0 2000 0 2000]);
grid
v
Thank you!!
David