MATLAB: Plotting a translated shape - matlab

I have a 7x2 matrix that contains data to plot out a shape. So my script is:
myMatrix = ([3,3;4,2;5,1;9,1;5,1;4,2;3,3]);
plot(myMatrix);
axis([-15 15 -15 15]);
I'm trying to translate it down 3 units and left 4 units. So that my shape will have the points (0,0) as the center. I could move it vertically simply by creating a new variable and defining it as -3+myMatrix. This will translate it down 3 units, but I am unable to move it along the x-axis.
There probably is a simple solution to this but I have been going to the documentation for matlab and googling but I couldn't find anything that will help me with this problem.

Try this:
plot(-3:3,myMatrix-3)
When no x is supplied to plot, the x coordinates are implicitly 1:length(y) when y is a vector or 1:size(y,1) for a matrix. This instead supplies -3:3 as x.

Related

Matlab: How to plot coordinate locations using x markers in a contour map?

I need to plot the locations of 3 treasures on a contour map.The coordinates are in a matrix (3x2) called "treasures", the first column contains the y coordinates, and the second column the x coordinates.
Using an X marker I was asked to plot the treasures locations using a marker size of 15, a line width of 4 and a red color.
How could I do that? the image should look like this
It looks like you need to read a basic tutorial on matlab first before you take on this project.
plotting scattered points can be done in matlab using the command plot. Assuming your treasure locations is x and y (both can be a vector for multiple points), you can plot those using
plot(x,y,'rx','markersize',15)

MeshGrid for Triangle Elements

I want to build a contourf plot of a certain aspect in my Plate. The plate is divided in triangle elements, which I have the coordinates (x,y) of each knot of the triangle.
So, How can I make a meshgrid for my knots so I can make my contourf plot?? I have the coordinates of everything and have the value of my function Z in each knot. (I'm a beginner in Matlab, sorry for this "basic" question)
If your goal is just to visualise the triangles then there is another way that's probably simpler and more robust (see the end of this post).
If you definitely need to generate contours then you will need to interpolate your triangular mesh over a grid. You can use the scatteredInterpolant class for this (documentation here). It takes the X and Y arguments or your triangular vertices (knots), as well as the Z values for each one and creates a 'function' that you can use to evaluate other points. Then you create a grid, interpolate your triangular mesh over the grid and you can use the results for the countour plot.
The inputs to the scatteredInterpolanthave to be linear column vectors, so you will probably need to reshape them using the(:)`notation.
So let's assume you have triangular data like this
X = [1 4; 8 9];
Y = [2 3; 4 5];
Z = [0.3 42; 16 8];
you would work out the upper and lower limits of your range first
xlimits = minmax(X(:));
ylimits = minmax(Y(:));
where the (:) notation serves to line up all the elements of X in a single column.
Then you can create a meshgrid that spans that range. You need to decide how fine that grid should be.
spacing = 1;
xqlinear = xlimits(1):spacing:xlimits(2);
yqlinear = ylimits(1):spacing:ylimits(2);
where linspace makes a vector of values starting at the first one (xlimits(1)) and ending at the third one (xlimits(2)) and separated by spacing. Experiment with this and look at the results, you'll see how it works.
These two vectors specify the grid positions in each dimension. To make an actual meshgrid-style grid you then call meshgrid on them
[XQ, YQ] = meshgrid(xqlinear, yqlinear);
this will produce two matrices of points. XQ holds the x-coordinates of every points in the grid, arranged in the same grid. YQ holds the y-coordinates. The two need to go together. Again experiment with this and look at the results, you'll see how it works.
Then you can put them all together into the interpolation:
F = scatteredInterpolant(X(:), Y(:), Z(:));
ZQ = F(XQ, YQ);
to get the interpolated values ZQ at each of your grid points. You can then send those data to contourf
contourf(XQ, YQ, ZQ);
If the contour is too blocky you will probably need to make the spacing value smaller, which will create more points in your interpolant. If you have lots of data this might cause memory issues, so be aware of that.
If your goal is just to view the triangular mesh then you might find trimesh does what you want or, depending on how your data is already represented, scatter. These will both produce 3D plots with wireframes or point clouds though so if you need contours the interpolation is the way to go.

draw an ellipse or contour in matlab

I have two vectors a = [1 1]' and b = [1 -1]' which are linearly independent.
I want to draw a shape like an ellipse or a contour around these points, so I can see the area which is spanned by these two vectors.
The picture below shows what I want to get. One of the blue vectors belongs to a and one of the red to b (I drew the mirrored vectors also for demonstration purpose). The green circle is what I want to draw.
How can I do that?
From your question and your example it seems to me that you don't have an entirely clear idea what you are trying to do. In order for MATLAB to plot anything, it will need at least a collection of points or an equation according to which this ellipse you want can be plotted.
The cleanest way to do so in this case would be to find the equations defining the ellipsoid. Using the information seen here, we see that we can describe any 2D-ellipse centered on the origin by the following equations:
x = a*cos(t)
y = b*sin(t)
The question then is: what should the values for our parameters a and b be? Since we have two points given that should satisfy these equations: [1,1] and [1,-1] we can deduce that a and b are equal to the square root of 2. Then we can plot the contour:
syms t % our equation's parameter is t
a = sqrt(2); b = sqrt(2);
x = a*cos(t);
y = b*sin(t);
ezplot(x,y) % plot the symbolic equation

Plotting a Line from a known point to points in a fitted curve in MATLAB

I have a set of data whose points I have plotted and fitted using a power of 2 fit in MATLAB. I'm trying to draw 3 lines to that curve as tangential lines. Each of these lines start from the co-ordinates of say, (x,y): (2,0) (4,0) (9,0).
Is it possible for MATLAB to draw lines from the curve to the first known point until the line has only one solution (tangent to the curve) with the curve?
I feel that this requires some sort of specified interval which tells MATLAB to step the co-ordinates until it finds the closest point. Does anyone know if this has been done or can be done at all?
From a point not lying on the curve, you want to draw a line that is tangent to it. In case of a convex function like y=2^x this is only possible from a point under the curve (not over it).
Since you already have the point (call it (a,b)), you need the slope of such a line. The slope is determined by the values (y-b)/(x-a) where (x,y) runs over the curve. Specifically, the "forward-looking" tangent has the slope equal to the minimum of (y-b)/(x-a) over all x>a. And the "backward-looking " tangent has the slope equal to the maximum of (y-b)/(x-a) over all x
Here is a very straightforward implementation of the above: I used find to restrict the search to either x>a or x<a and took min and max to find the slopes.
x = 0:0.01:4;
y = 2.^x;
a = 2;
b = 3;
k = min((y(find(x>a))-b)./(x(find(x>a))-a));
plot(x,y)
hold on
plot(x,k*(x-a)+b,'r')
k = max((y(find(x<a))-b)./(x(find(x<a))-a));
plot(x,k*(x-a)+b,'g')

Getting intermediate points generated by plot() in MATLAB

I've got a series of XY point pairs in MATLAB. These pairs describe points around a shape in an image; they're not a function, meaning that two or more y points may exist for each x value.
I can plot these points individually using something like
plot(B(:,1),B(:,2),'b+');
I can also use plot to connect the points:
plot(B(:,1),B(:,2),'r');
What I'm trying to retrieve are my own point values I can use to connect the points so that I can use them for further analysis. I don't want a fully connected graph and I need something data-based, not just the graphic that plot() produces. I'd love to just have plot() generate these points (as it seems to do behind the scenes), but I've tried using the linseries returned by plot() and it either doesn't work as I understand it or just doesn't give me what I want.
I'd think this was an interpolation problem, but the points don't comprise a function; they describe a shape. Essentially, all I need are the points that plot() seems to calculate; straight lines connecting a series of points. A curve would be a bonus and would save me grief downstream.
How can I do this in MATLAB?
Thanks!
Edit: Yes, a picture would help :)
The blue points are the actual point values (x,y), plotted using the first plot() call above. The red outline is the result of calling plot() using the second approach above. I'm trying to get the point data of the red outline; in other words, the points connecting the blue points.
Adrien definitely has the right idea: define a parametric coordinate then perform linear interpolation on the x and y coordinates separately.
One thing I'd like to add is another way to define your parametric coordinate so you can create evenly-spaced interpolation points around the entire shape in one pass. The first thing you want to do, if you haven't already, is make sure the last coordinate point reconnects to the first by replicating the first point and adding it to the end:
B = [B; B(1,:)];
Next, by computing the total distance between subsequent points then taking the cumulative sum, you can get a parametric coordinate that makes small steps for points close together and larger steps for points far apart:
distance = sqrt(sum(diff(B,1,1).^2,2)); %# Distance between subsequent points
s = [0; cumsum(distance)]; %# Parametric coordinate
Now, you can interpolate a new set of points that are evenly spaced around the edge along the straight lines joining your points using the function INTERP1Q:
sNew = linspace(0,s(end),100).'; %'# 100 evenly spaced points from 0 to s(end)
xNew = interp1q(s,B(:,1),sNew); %# Interpolate new x values
yNew = interp1q(s,B(:,2),sNew); %# Interpolate new y values
These new sets of points won't necessarily include the original points, so if you want to be sure the original points also appear in the new set, you can do the following:
[sAll,sortIndex] = sort([s; sNew]); %# Sort all the parametric coordinates
xAll = [B(:,1); xNew]; %# Collect the x coordinates
xAll = xAll(sortIndex); %# Sort the x coordinates
yAll = [B(:,2); yNew]; %# Collect the y coordinate
yAll = yAll(sortIndex); %# Sort the y coordinates
EXAMPLE:
Here's an example to show how the above code performs (I use 11 pairs of x and y coordinates, one of which is repeated for the sake of a complete example):
B = [0.1371 0.1301; ... %# Sample data
0.0541 0.5687; ...
0.0541 0.5687; ... %# Repeated point
0.0588 0.5863; ...
0.3652 0.8670; ...
0.3906 0.8640; ...
0.4090 0.8640; ...
0.8283 0.7939; ...
0.7661 0.3874; ...
0.4804 0.1418; ...
0.4551 0.1418];
%# Run the above code...
plot(B(:,1),B(:,2),'b-*'); %# Plot the original points
hold on; %# Add to the plot
plot(xNew,yNew,'ro'); %# Plot xNew and yNew
I'd first define some parametric coordinate along the different segments (i.e. between the data points)
s = 1:size(B,1);
Then, just use interp1 to interpolate in s space. e.g. If you want to generate 10 values on the line between data point 5 and 6 :
s_interp = linspace(5,6,10); % parametric coordinate interpolation values
x_coord = interp1(s,B(:,1),s_interp,'linear');
y_coord = interp1(s,B(:,2),s_interp,'linear');
This should do the trick.
A.
Actually there is a MATLAB function "improfile", which might help you in your problem. Lets say these are the 4 coordinates which you want to find the locations between these coordinates.
xi=[15 30 20 10];
yi=[5 25 30 50];
figure;
plot(xi,yi,'r^-','MarkerSize',12)
grid on
Just generate a random image and run the function
n=50; % total number of points between initial coordinates
I=ones(max([xi(:);yi(:)]));
[cx,cy,c] = improfile(I,xi,yi,n);
hold on, plot(cx,cy,'bs-','MarkerSize',4)
Hope it helps