This is my code:
%cirkel
t=linspace(0,2*pi);
r1=2;
x1=r1.*cos(t);
y1=r1.*sin(t);
cirkel=plot(x1,y1);
set(cirkel,'color','g')
axis equal
hold on
%cardeoide
t=linspace(0,2*pi);
r2=2*(cos(t)+1);
x2=r2.*cos(t);
y2=r2.*sin(t);
cardeoide=plot(x2,y2);
set(cardeoide, 'color','r')
hold off
I need to find the points where these curves intersect. I tried it by doing y1==y2 and x1==x2, but didn't get a good result (got a matrix full of numbers). Then I tried intersect(x1, x2). Also not a pleasing result. Then I resorted to this code. This gives a pretty accurate result. But I am not allowed to use this code (from school). So I was wondering is there a simpler solution?
thx in advance
To get the most accurate results you should not use your sampled points x1, x2, y1, y2.
These will be approximations to the two curves, and the probability that the intersection is one of the sampled points is low.
Instead, set up the equations to find the t where the curves intersect and solve for it (x1(t) = x2(t) and y1(t) = y2(t)).
PS. The reason you get a matrix full of numbers when doing y1 == y2 and x1==x2 is very obvious when you get a hang of how MATLAB does things.
Since you sample points on your curves, you will never find exactely the same point on both curves.
So. you should try to find the points with the smallest distance.
dists=pdist2([x1;y1],[x2;y2]);
[~,t1]=min(min(dists,[],2),[],1);
xInt1=x1(t1);
yInt1=y1(t1);
[~,t2]=min(min(dists,[],1),[],2);
xInt2=x2(t2);
yInt2=y2(t2);
Related
right now I have a 3d scatter plot with peaks that I need to find the volumes for. My data is from an image, so the x- and y- values indicate the pixel positions on the xy-plane, and the z value is the pixel value for each pixel.
Here's my scatter plot:
scatter3(x,y,z,20,z,'filled')
I am trying to find the "volume" of the peaks of the data, like drawn below:
I've tried findpeaks() but it gives me many local maxima without the the two prominent peaks that I'm looking for. In addition, I'm really stuck on how to establish the "base" of my peaks, because my data is from a scatter plot. I've also tried the convex hull and a linear surface fit, and get this:
But I'm still stuck on how to use any of these commands to establish an automated peak "base" and volume. Please let me know if you have any ideas or code segments to help me out, because I am stumped and I can't find anything on Stack Overflow. Sorry in advance if this is really unclear! Thank you so much!
Here is a suggestion for dealing with this problem:
Define a threshold for z height, or define in any other way which points from the scatter are relevant (the black plane in the leftmost figure below).
Within the resulted points, find clusters on the X-Y plane, to define the different regions to calculate. You will have to define manually how many clusters you want.
for each cluster, perform a Delaunay triangulation to estimate its volume.
Here is an example code for all that:
[x,y,z] = peaks(30); % some data
subplot 131
scatter3(x(:),y(:),z(:),[],z(:),'filled')
title('The original data')
th = 2.5; % set a threshold for z values
hold on
surf([-3 -3 3 3],[-4 4 -4 4],ones(4)*th,'FaceColor','k',...
'FaceAlpha',0.5)
hold off
ind = z>th; % get an index of all values of interest
X = x(ind);
Y = y(ind);
Z = z(ind);
clustNum = 3; % the number of clusters should be define manually
T = clusterdata([X Y],clustNum);
subplot 132
gscatter(X,Y,T)
title('A look from above')
subplot 133
hold on
c = ['rgb'];
for k = 1:max(T)
valid = T==k;
% claculate a triangulation of the data:
DT = delaunayTriangulation([X(valid) Y(valid) Z(valid)]);
[K,v] = convexHull(DT); % get the convex hull indices
% plot the volume:
ts = trisurf(K,DT.Points(:,1),DT.Points(:,2),DT.Points(:,3),...
'FaceColor',c(k));
text(mean(X(valid)),mean(Y(valid)),max(Z(valid))*1.3,...
num2str(v),'FontSize',12)
end
hold off
view([-45 40])
title('The volumes')
Note: this code uses different functions from several toolboxes. In any case that something does not work, first make sure that you have the relevant toolbox, there are alternatives to most of them.
Having already a mesh, maybe you could use the process described in https://se.mathworks.com/matlabcentral/answers/277512-how-to-find-peaks-in-3d-mesh .
If not, making a linear regression on (x,z) or (y,z) plane could make a base for you to find the peaks.
Out of experience in data with plenty of noise, selecting the peaks manually is often faster if you have small set of data to make the analysis. Just plot every peak with its number from findpeaks() and select the ones that are relevant to you. An interpolation to a smoother data can help to solve the problem in the long term (but creates a problem by itself).
Other option will be searching for peaks in the (x,z) and (y,z) planes, then having the amplitude of each peak in an (x) [or (y)] interval and from there make a integration for every area.
How can I
plot the point intersection of two curves in MATLAB?
And obtain that point in its mathematical form programmatically?
For simplicity I have taken two very basic curves :
y=x
y= cos(x)
I am able to plot the curves but cannot obtain the intersection point. See the screenshot:
I have tried the solutions proposed in this question but none of them worked for me.
Regards User. If I may ask, your objective is to obtain the exact point that intersect those two functions, or the nearest point to the intersection point? (the latter using approximation)
Here is an idea :
1) If your discretization : x=0:0.05:2; do contain the intersection point, you can use the intersect function in Matlab.
For example
intersect([1,2,3],[4,3,1])
will return a vector with two elements 1 and 3, the intersection of those two vectors.
To find the intersection point is to find the point x such that y1(x)=y2(x). So apply
yin = intersect(y1,y2);
After this, since your x is sorted, you should check the value in yin that has the same index in both y1 and y2.
The value that satisfy that condition is the intersection point in the y-axis.
2) If your x does not include the intersection point in x-axis, then use numerical methods. To find the roots of y2-y1. (or the points where g(x)=y2(x)-y1(x) = 0, since this is as same as y1(x)=y2(x))
You can try these first. Hope this will be useful. Thanks.
I've been using interp1 to plot curves to follow sets of datapoints, and for most of the datapoints it's been working:
But when I try it with another set of datapoints it doesn't follow them at all:
For both interpolations the code I'm using is just:
curve = interp1(x, y, 'pchip');
Where x is just a set of numbers that correspond to the x axis of each datapoint, and y is the values themselves.
I can't tell what is different about the second dataset that is causing the interp1 function to not follow the data.
So with thanks to #m.s. for providing his code, it turns out the issue is that with the second graph I was interpolating with x= -90:10:90, whereas if I interpolate with 1:19, in a similar manner to the first graph, then the problem is fixed.
Say for example I have data which forms the parabolic curve y=x^2, and I want to read off the x value for a given y value. How do I go about doing this in MATLAB?
If it were a straight line, I could just use the equation of the line of best fit to calculate easily, however I can't do this with a curved line. If I can't find a solution, I'll solve for roots
Thanks in advance.
If all data are arrays (not analytical expressions), I usually do that finding minimal absolute error
x=some_array;
[~,ind]=min(abs(x.^2-y0))
Here y0 is a given y value
If your data are represented by a function, you can use fsolve:
function y = myfun(x)
y=x^2-y0
[x,fval] = fsolve(#myfun,x0,options)
For symbolic computations, one can use solve
syms x
solve(x^2 - y0)
Assuming your two curves are just two vectors of data, I would suggest you use Fast and Robust Curve Intersections from the File Exchange. See also these two similar questions: how to find intersection points when lines are created from an array and Finding where plots may cross with octave / matlab.
I have calculated points for a recall-precision curve by varying a threshold and calculating recall and precision. I have plotted these points in a scatter graph as follows:
scatter(recall', precision')
I am trying to find the curve of best fit, but am not sure of the best way. I have tried this:
p = polyfit(recall', precision', 5)
r = polyval(p, recall')
plot(recall', precision', 'x');
hold on
plot(recall', r, '-');
hold off
But the problem with this is I have to estimate the degree of the polynomial (in this case 5).
you can try the program Eureqa Formulize. Its a free and easy to use tool for symbolic regression developed at Cornell Creative Machines Lab.
Regards,
Ben
You can try to take the logarithm of recall and precision variables and fit a line through them. The slope then should give a rough idea about the degree of the polynomial you might want to use, i.e.
p2 = polyfit(log(recall), log(precision), 1)