Idea
Im trying to plot a plane delimited by two vectors, using cross in matlab
Code
NM= [1 3; 2 4] //matrix
figure
hold on;
z = zeros(size(NM, 1), 1); //to use quiver3
quiver3(z, z, z, NM(:,1), NM(:,2), z, 0); //vectors plotted
grid on
view(45, 45);
s=sum(NM);
p = 10*(rand(3,1) - 0.5); // generation of points
O1=[NM(1,:) 0] // new vectors of length 3 ,
O2=[NM(2,:) 0] // to be used by cross
v3 = cross(O1,O2) //cross product to find the norm
[ x , y ] = meshgrid( p(1)+(-5:5) , p(2)+(-5:5) ); // points inside the plane
z = p(3) - (v3(1)*(x-p(1)) + v3(2)*(y-p(2)))/v3(3); // plane equation
surf(x,y,z) //the plane itself
The output is
Issue
The plane must be delimited by the vectors or the vectors must be inside the plane not outside.
The vectors do not appear inside the plane because you are choosing (0,0,0) as the starting point of the vectors while you are making the plane pass by the randomly chosen point p.
You either make the plane pass by (0,0,0) or use p as the starting point for the vectors when plotted with quiver3().
Here is a solution where I have chosen the second option:
vplane = [1 3 0; 2 4 0]'; % (column) vectors defining the plane
vnormal = cross(vplane(:,1), vplane(:,2)); % normal defining the orientation of the plane
figure; hold on; grid on; view(45, 45);
rng(1313) % seed for reproducible output
p = 10*(rand(3,1) - 0.5); % a point defining the position of the plane we want to plot with the given normal vector
P = repmat(p, 1, 2); % matrix with the given point repeated for easier use of quiver3()
quiver3(P(1,:), P(2,:), P(3,:), vplane(1,:), vplane(2,:), vplane(3,:), 0); % arrows representing the vectors defining the plane
[x,y] = meshgrid( p(1)+(-5:5), p(2)+(-5:5) ); % set of equally spaced points inside the plane
z = p(3) - (vnormal(1)*(x-p(1)) + vnormal(2)*(y-p(2))) / vnormal(3); % plane equation
surf(x,y,z) % plot the plane
and the result is the following:
Related
I am using MATLAB to print my simulation results. The results concerns a UAV's trajectory and waypoints that the UAV has to visit. The UAV is supposed to be equipped with a camera, whose range view is 10x10. Right now, the diagram shows the UAV's trajectory as a line visiting the waypoints. Is it possible, to show the camera's footprint, instead of the actual trajectory? I would like it to plot the rectangular camera's view to show the exhaustive coverage of the area. There is the option to plot the points as square, or cross, or cyrcles, but is it possible to set the boundaries of those?
Thank you in advance
The problem with using the marker size to indicate the range view is that there is no direct relation between the data units of your waypoints and the marker size. In other words, a value of 10 for the marker size doesn't necessarily mean that a side of a square marker is going to be 10 data units long (as defined by the scaling and limits of the axes).
An alternative is to plot square patches at each of your waypoints where the patch is aligned with the trajectory of the UAV. Here's how you can do this:
% Generate some sample data:
N = 20; % Number of waypoints
x = cumsum(5.*rand(1, N)); % X coordinates of UAV
y = cumsum(5.*rand(1, N)); % Y coordinates of UAV
% Compute vectors parallel and perpendicular to the trajectory at each point:
v = [diff(x); diff(y); zeros(1, N-1)]; % Vectors (1 per column)
v = bsxfun(#rdivide, v, sqrt(sum(v.^2, 1))); % Normalize each column to a unit vector
v = v(:, [1 1:end]); % Replicate a vector for starting point
vCross = cross(v, [zeros(2, N); ones(1, N)]); % Perpendicular vector
% Generate patch coordinates:
R = 10; % Range view
xPatch = [x+(R/2).*(v(1, :)+vCross(1, :)); ...
x+(R/2).*(v(1, :)-vCross(1, :)); ...
x-(R/2).*(v(1, :)+vCross(1, :)); ...
x-(R/2).*(v(1, :)-vCross(1, :))];
yPatch = [y+(R/2).*(v(2, :)+vCross(2, :)); ...
y+(R/2).*(v(2, :)-vCross(2, :)); ...
y-(R/2).*(v(2, :)+vCross(2, :)); ...
y-(R/2).*(v(2, :)-vCross(2, :))];
% Plot the patches and trajectory:
patch(xPatch, yPatch, [0 0.3 0], 'FaceAlpha', 0.25, 'EdgeColor', 'none');
hold on;
plot(x, y, '-', 'Color', [0.8 0 0], 'Marker', '.', 'MarkerSize', 12);
axis equal;
And here's a sample plot:
As a first attempt you can specify marker shape as square and set constant marker size, e.g.
plot(x,y,'s','markersize',10)
Here x and y are the vectors, holding the UAV coordinates. The letter 's' sets marker shape as square, and size is set to 10.
In reality, UAV trajectory is defined in a 3d space, where varying height above the ground corresponds to varying footprint size and shape. Taking this into account would require a bit more effort.
Also this assumes that the points are spaced closely enough otherwise there would be empty areas between markers.
I have an arbitrary shape, of which the exterior boundary has been traced in MATLAB using bwboundaries. Using regionprops, I can calculate the total area enclosed by this shape.
However, I want to know the area for only the parts of the shape that fall within a circle of known radius R centered at coordinates [x1, y1]. What is the best way to accomplish this?
There are a few ways to approach this. One way you could alter the mask before performing bwboundaries (or regionprops) so that it only includes pixels which are within the given circle.
This example assumes that you already have a logical matrix M that you pass to bwboundaries.
function [A, boundaries] = traceWithinCircle(M, x1, y1, R);
%// Get pixel centers
[x,y] = meshgrid(1:size(M, 1), 1:size(M, 2));
%// Compute their distance from x1, y1
distances = sqrt(sum(bsxfun(#minus, [x(:), y(:)], [x1, y1]).^2, 2));
%// Determine which are inside of the circle with radius R
isInside = distances <= R;
%// Set the values outside of this circle in M to zero
%// This will ensure that they are not detected in bwboundaries
M(~isInside) = 0;
%// Now perform bwboundaries on things that are
%// inside the circle AND were 1 in M
boundaries = bwboundaries(M);
%// You can, however, get the area by simply counting the number of 1s in M
A = sum(M(:));
%// Of if you really want to use regionprops on M
%// props = regionprops(M);
%// otherArea = sum([props.Area]);
end
And as an example
%// Load some example data
data = load('mri');
M = data.D(:,:,12) > 60;
%// Trace the boundaries using the method described above
B = traceWithinCircle(M, 70, 90, 50);
%// Display the results
figure;
hax = axes();
him = imagesc(M, 'Parent', hax);
hold(hax, 'on');
colormap gray
axis(hax, 'image');
%// Plot the reference circle
t = linspace(0, 2*pi, 100);
plot(x1 + cos(t)*R, y1 + sin(t)*R);
%// Plot the segmented boundaries
B = bwboundaries(M);
for k = 1:numel(B)
plot(B{k}(:,2), B{k}(:,1), 'r');
end
I am trying to plot a zplot in Matlab that displays a unit circle, centered at 0 along with the poles and zeros of the plot. I am not allowed to use any other matlab function such as zplane or pzplot to do this. So far I am able to plot a unit circle just fine but I am having trouble getting my plot to display more of the axis without warping my circle. I also am having a heard time finding the poles and zeros of my function and also how to display the poles as little x's and the zeros as little o's on my plot. Any help would be greatly appreciated! My assignment looks like this and must correctly handle cases such as
zplot([0 1 1], [0 1]);
zplot([0 1 1], [0 0 1]);
function zplot(b, a)
% ZPLOT Plot a zero-pole plot.
-1 -nb
B(z) b(1) + b(2)z + .... + b(nb+1)z
H(z) = ---- = ---------------------------------
-1 -na
A(z) a(1) + a(2)z + .... + a(na+1)z
% zplot(b, a) plots the zeros and poles which determined by vectors b and a
% The plot includes the unit circle and axes for reference, plotted in black.
% Each zero is represented with a blue 'o' and each pole with a red 'x' on the
%plot.
xmin;
xmax;
ymin;
ymax;
% vector of angles at which points are drawn
angle = 0:2*pi/100:2*pi;
% Unit radius
R = 1;
% Coordinates of the circle
x = R*cos(angle);
y = R*sin(angle);
% Plot the circle
plot(x,y);
axis ([xmin, xmax, ymin, ymax]);
grid on;
end
If you can't use pzplot() it is not hard. Here is a hint:
num = [1 4 1];%numerator coefficients of transfer function
den = [1 2 1];%denominator coefficients
z = roots(num)%zeros
p = roots(den)%poles
angle = 0:2*pi/100:2*pi;
xp = cos(angle);
yp = sin(angle);
figure(1)
scatter(z,zeros(length(z),1),'o');
hold on
scatter(p,zeros(length(p),1),'x');
plot(xp,yp);
axis equal
The output
Note that I haven't dealt with imaginary poles/zeros in this example. You'll need to calculate the proper x,y coordinates for a given imaginary pole or zero. (all the poles/zeros in this example are real, not imaginary)
Given a transfer function G, you can use the pzplot() command and add a circle to it.
G = tf([1 4 1],[1 2 1]);
angle = [0:0.1:2*pi+0.1];
xp = cos(angle);
yp = sin(angle);
figure(1)
hold on
pzplot(G);
plot(xp,yp);
axis equal;
This should give you the pole-zero plot with x's for poles, o's for zeros, and the unit circle.
Here is the result.
I am trying to sort random coordinates on a 2D cartesian grid using MATLAB into "bins" defined by a grid.
For example if I have a 2D domain with X ranging from [-1,1] and Y from [-1,1] and I generate some random coordinates within the domain, how can I "count" how many coordinates fall into each quadrant?
I realize that for and if statements can be used to determine the if each coordinate is within the quadrants, but I would like to scale this to much larger square grids that have more than just 4 quadrants.
Any concise and efficient approach would be appreciated!
Below is an example adapted from the code I mentioned.
The resulting binned points are be stored the variable subs; Each row contains 2d subscript indices of the bin to which a point was assigned.
% 2D points, both coordinates in the range [-1,1]
XY = rand(1000,2)*2 - 1;
% define equal-sized bins that divide the [-1,1] grid into 10x10 quadrants
mn = [-1 -1]; mx = [1 1]; % mn = min(XY); mx = max(XY);
N = 10;
edges = linspace(mn(1), mx(1), N+1);
% map points to bins
% We fix HISTC handling of last edge, so the intervals become:
% [-1, -0.8), [-0.8, -0.6), ..., [0.6, 0.8), [0.8, 1]
% (note the last interval is closed on the right side)
[~,subs] = histc(XY, edges, 1);
subs(subs==N+1) = N;
% 2D histogram of bins count
H = accumarray(subs, 1, [N N]);
% plot histogram
imagesc(H.'); axis image xy
set(gca, 'TickDir','out')
colormap gray; colorbar
xlabel('X'); ylabel('Y')
% show bin intervals
ticks = (0:N)+0.5;
labels = strtrim(cellstr(num2str(edges(:),'%g')));
set(gca, 'XTick',ticks, 'XTickLabel',labels, ...
'YTick',ticks, 'YTickLabel',labels)
% plot 2D points on top, correctly scaled from [-1,1] to [0,N]+0.5
XY2 = bsxfun(#rdivide, bsxfun(#minus, XY, mn), mx-mn) * N + 0.5;
line(XY2(:,1), XY2(:,2), 'LineStyle','none', 'Marker','.', 'Color','r')
I'm new to MATLAB and have a fundamental problem that I'm having issues finding online resources for. I have an equation for a circle: C = center + (radius*cos(theta)) + (radius*sin(theta)). I want to graph this circle IN ADDITION to other things I'm graphing beforehand...all in 3D. I've tried using theta = linspace(0,2*pi) but then in constructing my equation for the circle it says matrix sizes don't agree! If you could offer any help that would be great!
Here's an example of plotting a circle with a given radius and center (and assuming the circle lies in the plane z = 0):
radius = 2; %# Define your radius
center = [1 2]; %# Define your circle center [Cx Cy]
theta = linspace(0,2*pi); %# Create an array of theta values
X = center(1)+radius.*cos(theta); %# Create the X values for the circle
Y = center(2)+radius.*sin(theta); %# Create the Y values for the circle
Z = zeros(size(X)); %# Create the Z values for the circle (needed
%# for 3D plotting)
hold on; %# Add to the current existing plot
plot3(X,Y,Z); %# Plot your circle in 3D
And here are some links to online resources that should be a good starting point for learning the basics of plotting in MATLAB:
Using Basic Plotting Functions in MATLAB
PLOT function documentation
PLOT3 function documentation
HOLD function documentation
Since circle is fundamentally a 2D entity, you'll need to generate the points representing it to some known 2D plane embedded in 3D space. Then you'll be able to rotate, scale and translate it as you wish.
A simple demonstration code hopefully makes it clear:
n= 78; theta= linspace(0, 2* pi, n); c= [1 2 3]'; r= sqrt(2);
points= r*[cos(theta); sin(theta); zeros(1, n)]+ repmat(c, 1, n);
plot3(points(1,:), points(2,:), points(3,:), 's-')
axis equal, hold on
R= rref([rand(3) eye(3)]); R= R(:, 4: 6);
points= R* points;
plot3(points(1,:), points(2,:), points(3,:), 'ro')
I am not sure what you are trying to do, but consider this example:
theta = linspace(0,2*pi,100);
C = [0;0];
r = 1;
p = bsxfun(#plus, r.*[cos(theta);sin(theta)], C);
plot(p(1,:), p(2,:), '.-')
axis equal