Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Find angle between two lines

Subject: Find angle between two lines

From: Natalie Sin Hwee

Date: 16 Mar, 2010 14:24:22

Message: 1 of 14

Hello,

i have two lines:
- line 1 is between (0,3) and (4,3)
- line 2 is between (0,2) and (3,0)

How can i find the angle between these two lines because their origin is not (0,0) so i cant use the vector method to find the angle.

all i've managed to do is plot the two lines :
%line 1
x1=[0 4];
y1=[3 3];

line1=plot(x1,y1,'r')
hold on

% %line 2
x2=[0 3];
y2=[2 0];
line2=plot (x2,y2)

Please help
Thank you
Natalie

Subject: Find angle between two lines

From: Matt J

Date: 16 Mar, 2010 14:56:09

Message: 2 of 14

"Natalie Sin Hwee " <sin.ng09@imperial.ac.uk> wrote in message <hno4am$6ui$1@fred.mathworks.com>...
> Hello,
>
> i have two lines:
> - line 1 is between (0,3) and (4,3)
> - line 2 is between (0,2) and (3,0)
>
> How can i find the angle between these two lines because their origin is not (0,0) so i cant use the vector method to find the angle.
========

The angle between two lines is the angle between their direction vectors. The direction vectors of two lines can always be found by subtracting the position vectors of two points on the line

DirVector1=[4,3]-[0,3];
DirVector2=[0,2]-[3,0];

Angle=acos( dot(DirVector1,DirVector2)/norm(DirVector1)/norm(DirVector2) );

Subject: Find angle between two lines

From: Roger Stafford

Date: 16 Mar, 2010 16:48:22

Message: 3 of 14

"Matt J " <mattjacREMOVE@THISieee.spam> wrote in message <hno669$aj9$1@fred.mathworks.com>...
> .........
> DirVector1=[4,3]-[0,3];
> DirVector2=[0,2]-[3,0];
>
> Angle=acos( dot(DirVector1,DirVector2)/norm(DirVector1)/norm(DirVector2) );
----------
  The atan2 function is more robust accuracy-wise than acos when dealing with vectors that could be very nearly parallel. A glance at a plot of acos over its full range shows why. (Not in this particular case of course.)

 v1 = [4,3] - [0,3];
 v2 = [3,0] - [0,2];
 angle = atan2(norm(cross(v1,v2)),dot(v1,v2));

Roger Stafford

Subject: Find angle between two lines

From: Natalie Sin Hwee

Date: 17 Mar, 2010 12:17:08

Message: 4 of 14

"Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <hnocom$c9h$1@fred.mathworks.com>...
> "Matt J " <mattjacREMOVE@THISieee.spam> wrote in message <hno669$aj9$1@fred.mathworks.com>...
> > .........
> > DirVector1=[4,3]-[0,3];
> > DirVector2=[0,2]-[3,0];
> >
> > Angle=acos( dot(DirVector1,DirVector2)/norm(DirVector1)/norm(DirVector2) );
> ----------
> The atan2 function is more robust accuracy-wise than acos when dealing with vectors that could be very nearly parallel. A glance at a plot of acos over its full range shows why. (Not in this particular case of course.)
>
> v1 = [4,3] - [0,3];
> v2 = [3,0] - [0,2];
> angle = atan2(norm(cross(v1,v2)),dot(v1,v2));
>
> Roger Stafford

Thansk for replying ^^

can i just ask how does using atan2 differ from atan

i tried
theta= atan((y2-y1)/(x2-x1))-atan((y4-y3)/(x4-x3))

thanks!
natalie

Subject: Find angle between two lines

From: Roger Stafford

Date: 17 Mar, 2010 23:08:05

Message: 5 of 14

"Natalie Sin Hwee " <sin.ng09@imperial.ac.uk> wrote in message <hnqh84$p5k$1@fred.mathworks.com>...
> "Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <hnocom$c9h$1@fred.mathworks.com>...
> > .....
> > angle = atan2(norm(cross(v1,v2)),dot(v1,v2));
> > ......
>
> can i just ask how does using atan2 differ from atan
> i tried
> theta= atan((y2-y1)/(x2-x1))-atan((y4-y3)/(x4-x3))
> ......

  My apologies. The expression I gave really applies to a three-dimensional case. For a two-dimensional case a determinant can replace the cross product function and 'abs' replaces 'norm':

 A) angle = atan2(abs(det([v1,v2])),dot(v1,v2));

(where v1 and v2 are column vectors.) If you were to append a third dimension onto the vectors with z1=z2=z3=z4=0, (thereby having all points in the x-y plane) and use the normed cross product in the expression I gave before, it would reduce to this. Of course A) can also be written as

 angle = atan2(abs((x2-x1)*(y4-y3)-(y2-y1)*(x4-x3)), ...
                   (x2-x1)*(x4-x3)+(y2-y1)*(y4-y3));

where v1 = [x2-x1;y2-y1] and v2 = [x4-x3;y4-y3].

  Formula A) can be interpreted as giving the inner (non-negative) angle at the vertex of a triangle formed between two vectors with their bases both at this vertex and the two vector endpoints being the other two vertices. Such inner angles must of course lie between 0 and pi.

  This does not always give the same answer as the expression you wrote, Natalie. Notice that if you interchange the points (x1,y1) and (x2,y2), or else (x3,y3) and (x4,y4), your expression will remain unaltered, whereas A) will be changed to the supplement of the previous angle. Your expression has a range from -pi to +pi and A) ranges from 0 to +pi.

  If you remove the 'abs' from expression A):

B) angle = atan2(det([v1,v2]),dot(v1,v2));

this gives the angle measured from v1 around to v2 with the understanding that a counterclockwise direction is positive and a clockwise direction is negative. Its range is then from -pi to +pi.

  However even then B) is not equivalent to yours. As stated before, your expression does not change in value if v1 or v2 is reversed in sign, whereas the expression B) above switches to the opposite quadrant - that is, it increases or decreases by pi, whichever remains in range. All three expressions are therefore following different rules. What you use depends on what properties you wish your angle to possess.

  However, I suspect that you may not want to use one that does not reflect a switch to the opposite direction of either of your vectors. I cannot think offhand of an application that would require such a strange rule.

Roger Stafford

Subject: Find angle between two lines

From: Natalie Sin Hwee

Date: 8 Jul, 2010 15:06:03

Message: 6 of 14

Dear Roger,

thanks for getting back to me. I'm working on this bit of my code again.

I was wondering if there was a way to find the angles all anti clockwise because
i dont want to have 0 to pi and 0 to -pi due to some loop bits making it complicated.

I am now using:
        theta_rad(t,u)= (atan2(norm(cross(v1,v2)),dot(v1,v2)));
but it finds the smallest angle, either clockwise or anti clockwise.

is there a way so that it calculates angles only in 1 direction?

Thank you

Regards,
Natalie

Subject: Find angle between two lines

From: Natalie Sin Hwee

Date: 8 Jul, 2010 15:28:05

Message: 7 of 14

Dear Roger,

thanks for getting back to me. I'm working on this bit of my code again.

I was wondering if there was a way to find the angles all anti clockwise because
i dont want to have 0 to pi and 0 to -pi due to some loop bits making it complicated.

I am now using:
        theta_rad(t,u)= (atan2(norm(cross(v1,v2)),dot(v1,v2)));
but it finds the smallest angle, either clockwise or anti clockwise.

is there a way so that it calculates angles only in 1 direction?

Thank you

Regards,
Natalie

Subject: Find angle between two lines

From: Roger Stafford

Date: 8 Jul, 2010 19:04:05

Message: 8 of 14

"Natalie Sin Hwee " <sin.ng09@imperial.ac.uk> wrote in message <i14qq5$2rp$1@fred.mathworks.com>...
> Dear Roger,
>
> thanks for getting back to me. I'm working on this bit of my code again.
>
> I was wondering if there was a way to find the angles all anti clockwise because
> i dont want to have 0 to pi and 0 to -pi due to some loop bits making it complicated.
>
> I am now using:
> theta_rad(t,u)= (atan2(norm(cross(v1,v2)),dot(v1,v2)));
> but it finds the smallest angle, either clockwise or anti clockwise.
>
> is there a way so that it calculates angles only in 1 direction?
>
> Thank you
>
> Regards,
> Natalie
- - - - - - - -
  The expression you wrote in this last posting with the cross function in it can only apply to three dimensional space. The cross product is not defined in two dimensions. However, in three dimensions the notion of moving counterclockwise between vectors is no longer a meaningful one.

  In two dimensions if you have two column vectors va and vb and you wish to find the angle moving counterclockwise from va towards vb, and you don't want negative angles, it will necessarily be an angle that ranges from 0 to 2*pi. You can compute it as follows:

 ang = mod( atan2( det([va,vb]) , dot(va,vb) ) , 2*pi );

If va and vb are row vectors then the argument of the determinant changes to [va;vb].

  In your original March posting you had the vectors defined by a pair of points for each vector. If vector va points from point P1 to P2 and vector vb points from point P3 to P4, where P1 = (x1,y1), P2 = (x2,y2), P3 = (x3,y3), and P4 = (x4,y4), then you can use this formula:

 ang = mod( atan2( (x2-x1)*(y4-y3)-(y2-y1)*(x4-x3) , ...
                   (x2-x1)*(x4-x3)+(y2-y1)*(y4-y3) ) , 2*pi);

Roger Stafford

Subject: Find angle between two lines

From: Natalie Sin Hwee

Date: 8 Jul, 2010 21:35:04

Message: 9 of 14

"Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <i157f5$mkt$1@fred.mathworks.com>...
> "Natalie Sin Hwee " <sin.ng09@imperial.ac.uk> wrote in message <i14qq5$2rp$1@fred.mathworks.com>...
> > Dear Roger,
> >
> > thanks for getting back to me. I'm working on this bit of my code again.
> >
> > I was wondering if there was a way to find the angles all anti clockwise because
> > i dont want to have 0 to pi and 0 to -pi due to some loop bits making it complicated.
> >
> > I am now using:
> > theta_rad(t,u)= (atan2(norm(cross(v1,v2)),dot(v1,v2)));
> > but it finds the smallest angle, either clockwise or anti clockwise.
> >
> > is there a way so that it calculates angles only in 1 direction?
> >
> > Thank you
> >
> > Regards,
> > Natalie
> - - - - - - - -
> The expression you wrote in this last posting with the cross function in it can only apply to three dimensional space. The cross product is not defined in two dimensions. However, in three dimensions the notion of moving counterclockwise between vectors is no longer a meaningful one.
>
> In two dimensions if you have two column vectors va and vb and you wish to find the angle moving counterclockwise from va towards vb, and you don't want negative angles, it will necessarily be an angle that ranges from 0 to 2*pi. You can compute it as follows:
>
> ang = mod( atan2( det([va,vb]) , dot(va,vb) ) , 2*pi );
>
> If va and vb are row vectors then the argument of the determinant changes to [va;vb].
>
> In your original March posting you had the vectors defined by a pair of points for each vector. If vector va points from point P1 to P2 and vector vb points from point P3 to P4, where P1 = (x1,y1), P2 = (x2,y2), P3 = (x3,y3), and P4 = (x4,y4), then you can use this formula:
>
> ang = mod( atan2( (x2-x1)*(y4-y3)-(y2-y1)*(x4-x3) , ...
> (x2-x1)*(x4-x3)+(y2-y1)*(y4-y3) ) , 2*pi);
>
> Roger Stafford

Dear Roger,

That worked brilliantly! thank you SO much! u're a life saver!! ^^

Thank you very much!!!

Regards,
Natalie

Subject: Find angle between two lines

From: Natalie Sin Hwee

Date: 8 Jul, 2010 21:37:04

Message: 10 of 14

Sorry i forgot to ask,

If i was to apply this into 3D,

how can i apply ang = mod( atan2( det([v1;v2]) , dot(v1,v2) ) , 2*pi );
if e.g.
v1= [1,2,3]
v2= [4,5,6]
I tried but it says:

??? Error using ==> det
Matrix must be square.

Thanks
Natalie

Subject: Find angle between two lines

From: Roger Stafford

Date: 9 Jul, 2010 00:09:03

Message: 11 of 14

"Natalie Sin Hwee " <sin.ng09@imperial.ac.uk> wrote in message <i15ge0$91n$1@fred.mathworks.com>...
> Sorry i forgot to ask,
>
> If i was to apply this into 3D,
>
> how can i apply ang = mod( atan2( det([v1;v2]) , dot(v1,v2) ) , 2*pi );
> if e.g.
> v1= [1,2,3]
> v2= [4,5,6]
> I tried but it says:
>
> ??? Error using ==> det
> Matrix must be square.
>
> Thanks
> Natalie
- - - - - - - - - -
  As I mentioned earlier, in three dimensional space you will have to give up the notion of clockwise/counterclockwise rotation. If you have a vector on the earth pointing from earth center to Sydney, Australia and another pointing to Tokyo, there is no clockwise/counterclockwise criterion for deciding which is the "positive" way to rotate. Because of this, the usual convention is that the angle between the vectors is considered to be the smaller of the two angles in a full great circle containing two cities. Such an angle is always between 0 and pi, which is to say that it always lies in the first two quadrants. The other possible angle in the great circle of course then lies in the third or fourth quadrants, with the sum of these two being 2*pi.

  In three dimensions if va and vb are the vectors, the above (smaller) angle is given by:

 ang = atan2( norm(cross(va,vb)) , dot(va,vb) );

Notice that taking the norm of the cross product gives the first argument of atan2 a positive value, so the angle is constrained to lie in one of the first two quadrants.

Roger Stafford

Subject: Find angle between two lines

From: Natalie Sin Hwee

Date: 12 Jul, 2010 15:25:10

Message: 12 of 14

Dear Roger,

yes you're totally right! i'm so clueless. But thanks for your awesome explanation !! ^^

Thank you once again! You're a STAR!!

THank youThank you Thank you!!!

Kindest regards,
Natalie

"Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <i15pav$pgl$1@fred.mathworks.com>...
> "Natalie Sin Hwee " <sin.ng09@imperial.ac.uk> wrote in message <i15ge0$91n$1@fred.mathworks.com>...
> > Sorry i forgot to ask,
> >
> > If i was to apply this into 3D,
> >
> > how can i apply ang = mod( atan2( det([v1;v2]) , dot(v1,v2) ) , 2*pi );
> > if e.g.
> > v1= [1,2,3]
> > v2= [4,5,6]
> > I tried but it says:
> >
> > ??? Error using ==> det
> > Matrix must be square.
> >
> > Thanks
> > Natalie
> - - - - - - - - - -
> As I mentioned earlier, in three dimensional space you will have to give up the notion of clockwise/counterclockwise rotation. If you have a vector on the earth pointing from earth center to Sydney, Australia and another pointing to Tokyo, there is no clockwise/counterclockwise criterion for deciding which is the "positive" way to rotate. Because of this, the usual convention is that the angle between the vectors is considered to be the smaller of the two angles in a full great circle containing two cities. Such an angle is always between 0 and pi, which is to say that it always lies in the first two quadrants. The other possible angle in the great circle of course then lies in the third or fourth quadrants, with the sum of these two being 2*pi.
>
> In three dimensions if va and vb are the vectors, the above (smaller) angle is given by:
>
> ang = atan2( norm(cross(va,vb)) , dot(va,vb) );
>
> Notice that taking the norm of the cross product gives the first argument of atan2 a positive value, so the angle is constrained to lie in one of the first two quadrants.
>
> Roger Stafford

Subject: Find angle between two lines

From: Sathish Kumar

Date: 14 Nov, 2013 05:17:06

Message: 13 of 14

Thanks Roger. It cleared some basic doubts for me!!!

Subject: Find angle between two lines

From: Andrew Hernandez

Date: 26 Mar, 2014 22:00:12

Message: 14 of 14

"Roger Stafford" wrote in message <i15pav$pgl$1@fred.mathworks.com>...
> "Natalie Sin Hwee " <sin.ng09@imperial.ac.uk> wrote in message <i15ge0$91n$1@fred.mathworks.com>...
> > Sorry i forgot to ask,
> >
> > If i was to apply this into 3D,
> >
> > how can i apply ang = mod( atan2( det([v1;v2]) , dot(v1,v2) ) , 2*pi );
> > if e.g.
> > v1= [1,2,3]
> > v2= [4,5,6]
> > I tried but it says:
> >
> > ??? Error using ==> det
> > Matrix must be square.
> >
> > Thanks
> > Natalie
> - - - - - - - - - -
> As I mentioned earlier, in three dimensional space you will have to give up the notion of clockwise/counterclockwise rotation. If you have a vector on the earth pointing from earth center to Sydney, Australia and another pointing to Tokyo, there is no clockwise/counterclockwise criterion for deciding which is the "positive" way to rotate. Because of this, the usual convention is that the angle between the vectors is considered to be the smaller of the two angles in a full great circle containing two cities. Such an angle is always between 0 and pi, which is to say that it always lies in the first two quadrants. The other possible angle in the great circle of course then lies in the third or fourth quadrants, with the sum of these two being 2*pi.
>
> In three dimensions if va and vb are the vectors, the above (smaller) angle is given by:
>
> ang = atan2( norm(cross(va,vb)) , dot(va,vb) );
>
> Notice that taking the norm of the cross product gives the first argument of atan2 a positive value, so the angle is constrained to lie in one of the first two quadrants.
>
> Roger Stafford
Dear Roger,

It seems you have an excellent grasp on vector algebra and its application to finding the angle between two vectors in 3D geometry. I have a question that I believe you are well equipped to answer:

I have a 3D rectangular grid that was created using ndgrid which gives me coordinate arrays X,Y,Z:
     [X,Y,Z]=ndgrid[-xmin:xmax,-ymin:ymax,-zmin:zmax];

Then I create an empty matrix of zeros same size as this grid:
     M=zeros(size(X));

I have a vector between two points in this space that originates at point B (xb,yb,zb) and ends at point P (xp,yp,zp) - call this vector Vbp.
The direction vector Vbp,dir = [xp - xb; yp - yb; zp - zb]

I set all points in M to "1" within a sphere of radius R and origin at point P:
    M( (X-xp).^2 + (Y-yp).^2 + (Z-zp).^2)<=R^2 )=1;

And find the coordinates of all these points in the sphere ("sph"):
   [xsph,ysph,zsph]=ind2sub(size(M),find(M==1)
where length(xsph)=# voxels within sphere

Now, the directional vector from point P (i.e. origin of sphere) to each voxel within the sphere of radius r is:
   V(i)pi,dir = [xsph(i) - xp; ysph(i) - yp; zsph(i) - zp];
where i=1:# voxels within sphere

My question is this how to I compute the angle between Vbp,dir and V(i)pi,dir for all values of i in an efficient matter. Mainly, do I have to iterate through each voxel within the sphere, put another way, do I have to perform the calculation N times - where N is # voxels within sphere using the equation:
      theta=atan2( norm( cross( V(i)pi,dir, Vbp,dir ) ), dot( V(i)pi,dir, Vbp,dir ) )
          

OR is there a way to setup a matrix to solve the problem much more efficiently using matrix algebra

Your help is greatly appreciated.
Andrew Hernandez

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us