tags:

views:

3073

answers:

3

I have a very simple matlab question. What is the easiest way to find the point of intersection between two vectors. I am not familiar with the various matlab fuctions -- it seems like there should be one for this.

For example if I have one vector from (0,0) to (6,6) and another vector from (0,6) to (6,0), I need to determine that they intersect at (3,3)

Thanks.

+6  A: 

Well what you really have is 2 points on 2 different lines and you want to find the intersection. The easiest way is to find the equations of the two lines and then calculate the intersection.

The equation of a line is given by y=mx+b where m is the slope and b is the y-intercept. For one line you have two points which gives two equations. So, you can solve for the constants m and b. This gives the following two equations

 0=0*m+1*b  % using the first point x=y=0 into y=m*x+b
 6=6*m+1*b  % using the second point x=y=6

or in matrix form

 [ 0 ] = [ 0 1 ]* [ m ]
 [ 6 ]   [ 6 1 ]  [ b ] 

For the first line the constants can be calculated in MATLAB by

 C1 = inv([0 1;6 1]*[1;0]; % m=C1(1) and b=C(2)

Now that you have the equation for the two lines you can solve for the intersection by solving the following system of equations (which are obtained by manipulating the equation for a line)

 m_1*x-y = -b_1
 m_2*x-y = -b_2

All that is left is to write the above system of equations in matrix form and solve

 [x] = inv [m_1 -1] * [-b_1]
 [y]       [m_2 -1]   [-b_2]

or in MATLAB syntax

 I = inv(m_1 -1; m_2 -1]*[-b_1;-b_2]; % I is the intersection.

Notes

  • As per gnovice's comment if the the lines are actually line segments you need to check if the intersection is between the end points of the line segments

  • If the two slopes are equally, m_1=m_2 then there will either be no intersection or infinitely many intersections.

Azim
One additional point: If the two lines are being treated as line *segments*, an additional check is needed to see if the intersection point lies within the end points of each line.
gnovice
you should avoid using inv() to solve a linear system.
Amro
@Amro: can you explain why _inv_ should be avoided?
Azim
for AX=B, if A is square and invertible, then X = inv(A)*B is theoretically the same as X = A\B. But the computations involving the backslash operators are preferable because they require less computer time, less memory, and have better error-detection properties. Refer to http://www.mathworks.com/access/helpdesk/help/techdoc/math/f4-983672.html and http://www.mathworks.com/access/helpdesk/help/techdoc/math/f4-2224.html for more explanations
Amro
@Amro: Thanks for the explanation
Azim
+4  A: 

One solution is to use the equations found in this tutorial for finding the intersection point of two lines in 2-D. You can first create two matrices: one to hold the x coordinates of the line endpoints and one to hold the y coordinates.

x = [0 0; 6 6];  %# Starting points in first row, ending points in second row
y = [0 6; 6 0];

The equations from the above source can then be coded up as follows:

dx = diff(x);  %# Take the differences down each column
dy = diff(y);
den = dx(1)*dy(2)-dy(1)*dx(2);  %# Precompute the denominator
ua = (dx(2)*(y(1)-y(3))-dy(2)*(x(1)-x(3)))/den;
ub = (dx(1)*(y(1)-y(3))-dy(1)*(x(1)-x(3)))/den;

And you can now compute the intersection point of the two lines:

xi = x(1)+ua*dx(1);
yi = y(1)+ua*dy(1);

For the example in the question, the above code gives xi = 3 and yi = 3, as expected. If you want to check that the intersection point lies between the endpoints of the lines (i.e. they are finite line segments), you just have to check that the values ua and ub both lie between 0 and 1:

isInSegment = all(([ua ub] >= 0) & ([ua ub] <= 1));

A couple more points from the tutorial I linked to above:

  • If the denominator den is 0 then the two lines are parallel.
  • If the denominator and numerator for the equations for ua and ub are 0 then the two lines are coincident.
gnovice
+1 for directness and the implicit intersection check.
Azim
+1  A: 
jdmichal