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.
Related
I have an image of a cytoskeleton. There are a lot of small objects inside and I want to calculate the length between all of them in every axis and to get a matrix with all this data. I am trying to do this in matlab.
My final aim is to figure out if there is any axis with a constant distance between the object.
I've tried bwdist and to use connected components without any luck.
Do you have any other ideas?
So, the end goal is that you want to globally stretch this image in a certain direction (linearly) so that the distances between nearest pairs end up the closest together, hopefully the same? Or may you do more complex stretching ? (note that with arbitrarily complex one you can always make it work :) )
If linear global one, distance in x' and y' is going to be a simple multiplication of the old distance in x and y, applied to every pair of points. So, the final euclidean distance will end up being sqrt((SX*x)^2 + (SY*y)^2), with SX being stretch in x and SY stretch in y; X and Y are distances in X and Y between pairs of points.
If you are interested in just "the same" part, solution is not so difficult:
Find all objects of interest and put their X and Y coordinates in a N*2 matrix.
Calculate distances between all pairs of objects in X and Y. You will end up with 2 matrices sized N*N (with 0 on the diagonal, symmetric and real, not sure what is the name for that type of matrix).
Find minimum distance (say this is between A an B).
You probably already have this. Now:
Take C. Make N-1 transformations, which all end up in C->nearestToC = A->B. It is a simple system of equations, you have X1^2*SX^2+Y1^2*SY^2 = X2^2*SX^2+Y2*SY^2.
So, first say A->B = C->A, then A->B = C->B, then A->B = C->D etc etc. Make sure transformation is normalized => SX^2 + SY^2 = 1. If it cannot be found, the only valid transformation is SX = SY = 0 which means you don't have solution here. Obviously, SX and SY need to be real.
Note that this solution is unique except in case where X1 = X2 and Y1 = Y2. In this case, grab some other point than C to find this transformation.
For each transformation check the remaining points and find all nearest neighbours of them. If distance is always the same as these 2 (to a given tolerance), great, you found your transformation. If not, this transformation does not work and you should continue with the next one.
If you want a transformation that minimizes variations between distances (but doesn't require them to be nearly equal), I would do some optimization method and search for a minimum - I don't know how to find an exact solution otherwise. I would pick this also in case you don't have linear or global stretch.
If i understand your question correctly, the first step is to obtain all of the objects center of mass points in the image as (x,y) coordinates. Then, you can easily compute all of the distances between all points. I suggest taking a look on a histogram of those distances which may provide some information as to the nature of distance distribution (for example if it is uniformly random, or are there any patterns that appear).
Obtaining the center of mass points is not an easy task, consider transforming the image into a binary one, or some sort of background subtraction with blob detection or/and edge detector.
For building a histogram you can use histogram.
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 need to solve a minimization problem with Matlab and I'm wondering which is the easiest solution. All the potential solutions that I've been thinking in require lot of programming effort.
Suppose that I have a lat/long coordinate point (A,B), what I need is to search for the nearest point to this one in a map of lat/lon coordinates.
In particular, the latitude and longitude arrays are two matrices of 2030x1354 elements (1km distance) and the idea is to find the unique indexes in those matrices that minimize the distance to the coordinates (A,B), i.e., to find the closest values to the given coordinates (A,B).
Any help would be very appreciated.
Thanks!
This is always a fun one :)
First off: Mohsen Nosratinia's answer is OK, as long as
you don't need to know the actual distance
you can guarantee with absolute certainty that you will never go near the polar regions
and will never go near the ±180° meridian
For a given latitude, -180° and +180° longitude are actually the same point, so simply looking at differences between angles is not sufficient. This will be more of a problem in the polar regions, since large longitude differences there will have less of an impact on the actual distance.
Spherical coordinates are very useful and practical for purposes of navigation, mapping, and that sort of thing. For spatial computations however, like the on-surface distances you are trying to compute, spherical coordinates are actually pretty cumbersome to work with.
Although it is possible to do such calculations using the angles directly, I personally don't consider it very practical: you often have to have a strong background in spherical trigonometry, and considerable experience to know its many pitfalls -- very often there are instabilities or "special points" you need to work around (the poles, for example), quadrant ambiguities you need to consider because of trig functions you've introduced, etc.
I've learned to do all this in university, but I also learned that the spherical trig approach often introduces complexity that mathematically speaking is not strictly required, in other words, the spherical trig is not the simplest representation of the underlying problem.
For example, your distance problem is pretty trivial if you convert your latitudes and longitudes to 3D Cartesian X,Y,Z coordinates, and then find the distances through the simple formula
distance (a, b) = R · arccos( a/|a| · b/|b| )
where a and b are two such Cartesian vectors on the sphere. Note that |a| = |b| = R, with R = 6371 the radius of Earth.
In MATLAB code:
% Some example coordinates (degrees are assumed)
lon = 360*rand(2030, 1354);
lat = 180*rand(2030, 1354) - 90;
% Your point of interest
P = [4, 54];
% Radius of Earth
RE = 6371;
% Convert the array of lat/lon coordinates to Cartesian vectors
% NOTE: sph2cart expects radians
% NOTE: use radius 1, so we don't have to normalize the vectors
[X,Y,Z] = sph2cart( lon*pi/180, lat*pi/180, 1);
% Same for your point of interest
[xP,yP,zP] = sph2cart(P(1)*pi/180, P(2)*pi/180, 1);
% The minimum distance, and the linear index where that distance was found
% NOTE: force the dot product into the interval [-1 +1]. This prevents
% slight overshoots due to numerical artifacts
dotProd = xP*X(:) + yP*Y(:) + zP*Z(:);
[minDist, index] = min( RE*acos( min(max(-1,dotProd),1) ) );
% Convert that linear index to 2D subscripts
[ii,jj] = ind2sub(size(lon), index)
If you insist on skipping the conversion to Cartesian and use lat/lon directly, you'll have to use the Haversine formula, as outlined on this website for example, which is also the method used by distance() from the mapping toolbox.
Now, all of this is valid for the whole Earth, provided you find the smooth spherical Earth accurate enough an approximation. If you want to include the Earth's oblateness or some higher order shape model (or God forbid, distances including terrain), you need to do far more complicated stuff. But I don't think that is your goal here :)
PS - I wouldn't be surprised that if you would write everything out that I did, you'll probably re-discover the Haversine formula. I just prefer to be able to calculate something as simple as distances along the sphere from first principles alone, rather than from some black box formula you had implanted in your head sometime long ago :)
Let Lat and Long denote latitude and longitude matrices, then
dist2=sum(bsxfun(#minus, cat(3,A,B), cat(3,Lat,Long)).^2,3);
[I,J]=find(dist2==min(dist2(:)));
I and J contain the indices in A and B that correspond to nearest point. Note that if there are multiple answers, I and J will not be scalar values, but vectors.
I have some 3D parametric equations that I plot in matlab/octave and would like to find out where they intersect how can I go about doing this. Please note this is just a simple example I plan on having multiple parametric equations that will intersect.
What I'm trying to do is begin and end each plot at an intersection point.
My first thought was putting all the intersection points found at (t) into an array and plotting the ones I want I just couldn't figure out how to get the intersections at (t)
Example matlab/octave code below:
clear all, clf
t = 0:pi/60:2.45*pi;
plot3 ((t).*cos(t), (t).*sin(t), (t),'b*');
hold on
plot3 ((t).*sin((t)), (t).*cos((t)), (t),'r');
Here's an image with the arrows pointing to the intersecting points
I'd say that it is better to solve this system of equations analytically if possible.
Look, with your original code (just the plotted line styles were changed)
clear all, clf
t = 0:pi/60:2.45*pi;
plot3 ((t).*cos(t), (t).*sin(t), (t),'*b-');
hold on
plot3 ((t).*sin((t)), (t).*cos((t)), (t),'or-');
I have this picture at one of the intersections:
Its nice because the two plots intersect perfectly with each other in one of the plotted points.
Now consider the following situation. I changed your second line to
t = 0:0.05:2.45*pi;
Now I see this at the intersection point:
Now the two 3D polygonal lines generated for different values of t parameter in general case will not have any common points. So simple check for intersection of those linear segments will fail.
Same thing will happed if you update your equations to more complicated ones with more complicated dependencies over t (otherwise you are really lucky).
Analytical solution (if possible) will be unbeatable here.
As a numerical way to do this, consider distance D from an arbitrary point P1(x1(t1),y1(t1),z1(t1)) on one line to an arbitrary point P2(x2(t2),y2(t2),z2(t2)) on another one. Then find minimum of D as a function of two independent parameters t1 and t2. If D at minimum is zero (or very close to zero), then these two lines intersect. Otherwise they just pass each other.
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);