Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Angle between two vectors

3,877 views
Skip to first unread message

y Mehta

unread,
Jul 9, 2007, 5:16:29 PM7/9/07
to
How do I find the angle between two unit vectors a and b? I know I
can find cosine theta by the following formula:

theta = acos(dot(a,b));

However, how do I know whether the angle is actually theta, or -theta
or pi-theta or pi+theta??

Notice that the vectors are in three dimension (3d).

Thanks,
-YM

Roger Stafford

unread,
Jul 9, 2007, 10:57:36 PM7/9/07
to
In article <ef5ce...@webcrossing.raydaftYaTP>, "y Mehta"
<mehtayogesh@gmail.(DOT).com> wrote:

---------------------
It is usually understood that the angle between two three-dimensional
vectors is measured by the shortest great circle path between them, which
means that it must lie between 0 and pi radians. To get such an answer,
the best method, in my opinion, is this:

angle = atan2(norm(cross(a,b)),dot(a,b));

Since the first argument must be non-negative, the angle will lie
somewhere in the two first quadrants, and thus be between 0 and pi. This
formula remains valid even if a and b are not unit vectors.

Your 'acos' formula gives the correct answer with unit vectors as it
stands, but it encounters an accuracy problem for angles that are near 0
or pi. This is the main reason for my preference for the 'atan2' method.

Roger Stafford

Greg Heath

unread,
Jul 10, 2007, 3:30:26 AM7/10/07
to
On Jul 9, 5:16 pm, "y Mehta" <mehtayogesh@gmail.(DOT).com> wrote:
> How do I find the angle between two unit vectors a and b? I know I
> can find cosine theta by the following formula:
>
> theta = acos(dot(a,b));
>

Invalid since it is possible that abs(dot(a,b)) > 1.

costheta = dot(a,b)/(norm(a)*norm(b));
theta = acos(costheta);

will give you the anser in the interval [0,pi].

> However, how do I know whether the angle is
> actually theta, or -theta or pi-theta or pi+theta??

Angles between vectors only lie in the interval [0,pi].

> Notice that the vectors are in three dimension (3d).

Dimensionality of the original space is irrelevant. As long as
norm(a)*norm(b) > 0, the vectors uniquely define a 2-d space when
dot(a,b) ~= 0 and a unique 1-d space otherwise.

Hope this helps.

Greg

Roger Stafford

unread,
Jul 10, 2007, 4:27:08 AM7/10/07
to
In article <1184052626.3...@n2g2000hse.googlegroups.com>, Greg
Heath <he...@alumni.brown.edu> wrote:

---------------
Greg, Y Mehta did specifically state that a and b are unit vectors, so
his formula is in fact correct as it stands, though subject to increasing
errors as its dot product approaches +1 or -1. When a and b are nearly
parallel, the same kind of trouble occurs with the formula you have given
here. In such cases there is a real need to combine the scalar dot
product with the vector cross product in order to make use of both the
sine and cosine in calculating the angle accurately, which is what the
'tan2' formula does.

Roger Stafford

Greg Heath

unread,
Jul 10, 2007, 5:55:26 PM7/10/07
to
On Jul 10, 4:27 am, ellieandrogerxy...@mindspring.com.invalid (Roger
Stafford) wrote:
> In article <1184052626.324470.175...@n2g2000hse.googlegroups.com>, Greg

Thanks.

For some problem in the past (probably single precision?) I got better
accuracy using

sign(sintheta)*acos(costheta)

instead of atan2.

Hope this helps.

Greg

Hope this helps.

Roger Stafford

unread,
Jul 10, 2007, 7:22:36 PM7/10/07
to
In article <1184104526....@n60g2000hse.googlegroups.com>, Greg
Heath <he...@alumni.brown.edu> wrote:

> For some problem in the past (probably single precision?) I got better
> accuracy using
>
> sign(sintheta)*acos(costheta)
>
> instead of atan2.

---------------
I don't know why that would be better, Greg. The acos(costheta) is
subject to the same problem as before. When costheta is very near 1, the
accuracy is very much inferior to that of 'atan2'. I would think this
would be equally true in single precision.

Here's a concrete example of what I am referring to:

format long
a = pi*(1-1/10^8); % Choose an angle a little below pi
a2 = atan2(sin(a),cos(a)); % Use atan2
a3 = acos(cos(a)); % Use acos
[a;a2;a3;a-a2;a-a3] % Compare results

a = pi/2*1.123; % Now select an angle near pi/2
a2 = atan2(sin(a),cos(a)); % atan2 again
a3 = acos(cos(a)); % Then acos
[a;a2;a3;a-a2;a-a3] % Make the same comparisons

ans =

3.14159262217387
3.14159262217387
3.14159262378747
0
-0.00000000161360

ans =

1.76400427499067
1.76400427499067
1.76400427499067
0.00000000000000
0.00000000000000

As you see, there is a very distinct loss of accuracy in 'acos' for angles
near pi. Some seven entire decimal places have been lost - that is,
errors are several million times as large as normal. On the other hand,
the angle near pi/2 yields the customary 1 in 2^52 accuracy.

Roger Stafford

salih tuna

unread,
Dec 10, 2007, 6:59:47 AM12/10/07
to
hello,
how can i calculate the angles so that they are in the range
0-360 degrees?
thanks
salih


"y Mehta" <mehtayogesh@gmail.(DOT).com> wrote in message
<ef5ce...@webcrossing.raydaftYaTP>...

salih tuna

unread,
Dec 10, 2007, 7:00:24 AM12/10/07
to
hello,
how can i calculate the angles so that they are in the range
0-360 degrees?
thanks
salih


"y Mehta" <mehtayogesh@gmail.(DOT).com> wrote in message
<ef5ce...@webcrossing.raydaftYaTP>...

Roger Stafford

unread,
Dec 10, 2007, 1:35:28 PM12/10/07
to
"salih tuna" <sali...@gmail.com> wrote in message <fjj9nj$fia
$1...@fred.mathworks.com>...
--------
Y Mehta's question involved angles between vectors in three-dimensional
space. I can think of no reasonable definition for a canonical angle between
such vectors which ranges from 0 to 360 degrees (0 to 2*pi radians.)

However, if you are in two-dimensional space, then you can speak of the
non-negative angle measured counterclockwise from vector a to vector b,
and this would give the range you have requested. If a = [x1,y1] and b =
[x2,y2], then such an angle is given in matlab by:

angle = mod(atan2(y2-y1,x2-x1),2*pi); % Range: 0 to 2*pi radians

(Multiply this answer by 180/pi to get degrees.)

Roger Stafford

salih tuna

unread,
Dec 11, 2007, 6:20:21 AM12/11/07
to
Hi,
thanks a lot for your reply. yes they are in 2d, sorry i
forgot to mention.
i tried to apply the formula but i am getting wrong result.
for example i want to calculate the angle between a = [1 1]
and b = [0 -1] which is 225 degrees. with this formulae i
got 243.4. i couldn't see where i am doing the mistake.
thanks a lot in advance
salih


"Roger Stafford" <ellieandr...@mindspring.com.invalid>
wrote in message <fjk0tg$jli$1...@fred.mathworks.com>...

Roger Stafford

unread,
Dec 11, 2007, 8:56:20 AM12/11/07
to
"salih tuna" <sali...@gmail.com> wrote in message <fjlrpl$gii
$1...@fred.mathworks.com>...

> Hi,
> thanks a lot for your reply. yes they are in 2d, sorry i
> forgot to mention.
> i tried to apply the formula but i am getting wrong result.
> for example i want to calculate the angle between a = [1 1]
> and b = [0 -1] which is 225 degrees. with this formulae i
> got 243.4. i couldn't see where i am doing the mistake.
> thanks a lot in advance
> salih
>
> "Roger Stafford" <ellieandr...@mindspring.com.invalid>
> wrote in message <fjk0tg$jli$1...@fred.mathworks.com>...
> > angle = mod(atan2(y2-y1,x2-x1),2*pi); % Range: 0 to 2*pi
--------
I certainly owe you an apology, Salih. That formula I gave you is very, very
wrong. I can't imagine what I was thinking about when I wrote it. Chalk it up
to momentary insanity! :-) The correct computation should be as follows.

Assuming a = [x1,y1] and b = [x2,y2] are two vectors with their bases at the
origin, the non-negative angle between them measured counterclockwise
from a to b is given by

angle = mod(atan2(x1*y2-x2*y1,x1*x2+y1*y2),2*pi);

As you can see, this bears a close relationship to the three-dimensional
formula I wrote last July 10. The quantities, x1*y2-x2*y1 and x1*x2+y1*y2
are, respectively, the sine and cosine of the counterclockwise angle from
vector a to vector b, multiplied by the product of their norms - that is, their
cross product and the dot product restricted to two dimensions. The 'atan2'
function then gives the angle between them ranging from -pi to +pi, and the
'mod' operation changes this so as to range from 0 to 2*pi, as you requested.

Roger Stafford


salih tuna

unread,
Dec 11, 2007, 10:29:00 AM12/11/07
to
Roger hi,
thanks a lot for your help but i am afraid something is
still missing. i tried the formulae on the same example of
a = [1 1]and b = [0 -1] (both passing through origin).
the answer i got is 315 instead of 225.
sorry i am taking a lot of your time :)
thanks
salih

"Roger Stafford" <ellieandr...@mindspring.com.invalid>
wrote in message <fjm4u4$i8o$1...@fred.mathworks.com>...

Roger Stafford

unread,
Dec 11, 2007, 2:32:07 PM12/11/07
to
"salih tuna" <sali...@gmail.com> wrote in message <fjmabs$9fh
$1...@fred.mathworks.com>...

> Roger hi,
> thanks a lot for your help but i am afraid something is
> still missing. i tried the formulae on the same example of
> a = [1 1]and b = [0 -1] (both passing through origin).
> the answer i got is 315 instead of 225.
> sorry i am taking a lot of your time :)
> thanks
> salih
-----
Hi Salih. I get 225 degrees for that example with a = [1,1] and b = [0,-1],
which is correct. Are you sure you didn't have x2 and y1 interchanged by
mistake? That would get you an erroneous answer of 315. You should have x1
= 1, y1 = 1, x2 = 0, and y2 = -1.

Roger Stafford

baris kazar

unread,
Dec 28, 2007, 11:11:38 AM12/28/07
to
"Roger Stafford"
<ellieandr...@mindspring.com.invalid> wrote in
message <fjk0tg$jli$1...@fred.mathworks.com>...

Hi,-
how can we generalize this to 3-D vectors? Think of a
plane on 3-D space and you have vectors on this plane. I
wanna know the angle between 2 vectors in the range 0-2pi.
or at least -pi to pi. I have 3 vectors. One (First)
vector is the same all the time. I wanna know the relative
positions of the other two vector wrt the firsy one. Thus,
i need angles in the range 0 to 2pi or -pi to pi.
Thanks in advance

Bruno Luong

unread,
Dec 28, 2007, 1:22:57 PM12/28/07
to
"baris kazar" <mbkazar...@gmail.com> wrote in message
<fl377q$4ip$1...@fred.mathworks.com>...

>
> Hi,-
> how can we generalize this to 3-D vectors? Think of a
> plane on 3-D space and you have vectors on this plane. I
> wanna know the angle between 2 vectors in the range 0-2pi.

The problem is depends on where you look (from above or from
below the plane), you will see the angle between vectors on
this plane reverse the sign (draw them on a transparent
glass and try to look from both sides). In 3D there is
nothing that could tell us whereas looking from one way or
from another is more "correct".

Think like a fish or a bird, not like a man.

Bruno

baris kazar

unread,
Dec 28, 2007, 1:50:50 PM12/28/07
to
"Bruno Luong" <b.l...@fogale.fr> wrote in message <fl3eu1
$d3$1...@fred.mathworks.com>...

Hi Bruno,
Thanks, but i partially dont agree with you. If you
choose a reference of point which the start point of the
first vector, it is not important for me whether you look
from above or below the plane. I need relative positions
but not the absolute positions. I think i indicated this
above.
Anyways, if someone comes up with an idea, please post
here. I am very curious about a solution.
Best regards

Roger Stafford

unread,
Dec 28, 2007, 3:36:34 PM12/28/07
to
"baris kazar" <mbkazar...@gmail.com> wrote in message <fl377q$4ip
$1...@fred.mathworks.com>...
> Hi,-
> how can we generalize this to 3-D vectors? Think of a
> plane on 3-D space and you have vectors on this plane. I
> wanna know the angle between 2 vectors in the range 0-2pi.
> or at least -pi to pi. I have 3 vectors. One (First)
> vector is the same all the time. I wanna know the relative
> positions of the other two vector wrt the firsy one. Thus,
> i need angles in the range 0 to 2pi or -pi to pi.
> Thanks in advance
---------
As Bruno has pointed out, the angle between two three-dimensional vectors
depends on which sense one gives to a vector orthogonal to their plane. It
isn't clear what you meant by, "the relative positions of the other two vector
wrt the firsy one." The vector cross product of the second two vectors will be
a vector orthogonal to their plane. Perhaps you mean that the angle between
them is to be considered positive if this cross product lies on the same side
of the plane as this first vector, and negative otherwise. If that is the case,
then let your first, second, and third vectors be designated as x, y, and z,
respectively. A matlab formula for calculating the angle between y and z will
then be:

c = cross(y,z);
angleyz = sign(dot(x,c))*atan2(norm(c),dot(y,z));

The value of 'angleyz' will range from -pi to +pi. If you want it to range from
0 to 2*pi, then apply the 'mod' function as I did on Dec. 11 in this thread.

Roger Stafford

baris kazar

unread,
Dec 28, 2007, 3:50:02 PM12/28/07
to
"Roger Stafford"
<ellieandr...@mindspring.com.invalid> wrote in
message <fl3moi$pvc$1...@fred.mathworks.com>...
Hi Roger,-
yes, this is one step closer to what i need but not
exactly. Let's take a numeric example:
x=(1,0,0); y=(1,0,1) and z=(1,0-1)
let's call the angle between x and y theta.
Then i wanna get 2pi-theta for the angle between x and z.
i dont have access y and z at the same time.
hope that this problem statement is clear.
Thanks much for your reply
Best regards

Bruno Luong

unread,
Dec 28, 2007, 4:38:03 PM12/28/07
to
"baris kazar" <mbkazar...@gmail.com> wrote in message
> yes, this is one step closer to what i need but not
> exactly. Let's take a numeric example:
> x=(1,0,0); y=(1,0,1) and z=(1,0-1)
> let's call the angle between x and y theta.
> Then i wanna get 2pi-theta for the angle between x and z.
> i dont have access y and z at the same time.
> hope that this problem statement is clear.

Assuming a human being (e.g., all the birds, or you) can go
anywhere in R3, and can look in any direction (a fair
assumption isn't it?).

VIEW1: Goto the point (0,-1,0) look toward the direction
(0,1,0): you see angle(x,y)=-pi/4, and angle(x,z)=pi/4.

VIEW2: Goto the point (0,+1,0) look toward the direction
(0,-1,0): you see angle(x,y)=+pi/4, and angle(x,z)=-pi/4.

In both cases you have angle(x,y) = -angle(x,z) modulo 2*pi,
as your wish expressed above with "theta".

BUT
CASE1/VIEW1: angle(x,y)=-pi/4; angle(x,z)=pi/4; angle(y,z)=pi/2.

CASE2/VIEW2: angle(x,y)=+pi/4; angle(x,z)=-pi/4;
angle(y,z)=-pi/2.

ALL angles change the sign when you change the side. You
simply cannot decide which is a *right* way, because the
opposite is also right as much.

THERE IS NO UNIQUE WAY TO DEFINE ANGLE IN R3.

Bruno

Roger Stafford

unread,
Dec 28, 2007, 4:52:57 PM12/28/07
to
"baris kazar" <mbkazar...@gmail.com> wrote in message <fl3nhq$3tc
$1...@fred.mathworks.com>...

> Hi Roger,-
> yes, this is one step closer to what i need but not
> exactly. Let's take a numeric example:
> x=(1,0,0); y=(1,0,1) and z=(1,0-1)
> let's call the angle between x and y theta.
> Then i wanna get 2pi-theta for the angle between x and z.
> i dont have access y and z at the same time.
> hope that this problem statement is clear.
> Thanks much for your reply
> Best regards
--------
You will have to try harder to explain your problem, if I am to understand
you, Baris. The example you gave has x, y, and z all in the same plane. You
didn't state previously that all your vectors are coplanar. Are they? But
whether they are or not, this doesn't explain how you would define the angle
theta between x and y. It could be plus pi/4 or it could be minus pi/4 (or
7/4*pi.) Which one would you choose and according to what criterion? It
would depend on which side of the plane, in this case the x-z plane, is
regarded as its positive side - along the plus y-axis, or along the negative
side of the y-axis. Also it depends on whether you are moving from x
towards y or from y towards x if you are adhering to right-hand cross
product direction conventions.

Select two arbitrary vectors in three-dimensional space (x1,y1,z1) and
(x2,y2,z2) and try to think of a consistent way of defining the angle between
them without reference to any other vector that would allow this quantity to
range over the full four quadrants, 0 to 2*pi. I think you will find this a
difficult thing to do in any way that could reasonably be considered canonical.
In two dimensions, there is a clearly defined counterclockwise direction from
vector x to vector y which would give you the range you desire. In three
dimensions, you lose the sense of what is a "counterclockwise" direction. You
can go from x to y along either of two great circle paths and one direction will
give the supplement angle to the opposite direction. If you always select the
shortest path, then your angle range is restricted to [0,pi].

If one vector of each pair is restricted to a particular fixed vector, as your
previous wordage seemed to imply, I still don't see what criterion you wish to
use to define these angles. For example, you can move from the fixed vector
by one degree in all possible directions giving a cone, but which half of these
angles should be adjusted so as to be the supplements (that is 359 degrees,)
of those on the opposite side? If you are restricting your vectors to all be
coplanar, then which side of such a plane is to be considered its "positive"
side?

Roger Stafford

baris kazar

unread,
Dec 29, 2007, 12:47:16 AM12/29/07
to
"Bruno Luong" <b.l...@fogale.fr> wrote in message
<fl3qbq$l6j$1...@fred.mathworks.com>...

> THERE IS NO UNIQUE WAY TO DEFINE ANGLE IN R3.
>
> Bruno

Hi Bruno,
i did not say THERE IS.
Best regards,

baris kazar

unread,
Dec 29, 2007, 12:49:03 AM12/29/07
to
"Roger Stafford"
<ellieandr...@mindspring.com.invalid> wrote in
message <fl3r7p$5nt$1...@fred.mathworks.com>...

> You will have to try harder to explain your problem,
if I am to understand
> you, Baris. The example you gave has x, y, and z all in
the same plane. You
> didn't state previously that all your vectors are
coplanar. Are they? But

I think i did:


> > Hi,-
> > how can we generalize this to 3-D vectors? Think of a
> > plane on 3-D space and you have vectors on this plane.
I
> > wanna know the angle between 2 vectors in the range 0-
2pi.

I think i might not have done a good in explaining the
problem. Sorry about that.
Best regards,

baris kazar

unread,
Dec 29, 2007, 12:53:08 AM12/29/07
to
"Roger Stafford"
<ellieandr...@mindspring.com.invalid> wrote in
message <fl3r7p$5nt$1...@fred.mathworks.com>...

Hi Roger,-
these are excellent questions.
one can choose to look at the plane from +ive infinity
(above) or from -ive infinity (below).

I know that in 3D there is no notion of CW or CCW. However,
you can define it locally wrt a point/vector as long as
they are on a plane by defining from which side you are
looking at.

Anyways, i dont wanna confuse anyone any more.
I will find another solution to this problem.
Best regards

Bruno Luong

unread,
Dec 29, 2007, 4:16:29 AM12/29/07
to
"baris kazar" <mbkazar...@gmail.com> wrote in message
<fl4nc4$47i$1...@fred.mathworks.com>...

>
> However,
> you can define it locally wrt a point/vector as long as
> they are on a plane by defining from which side you are
> looking at.

That's a good way. Pick a side.

That's easy.

1. Select two arbitrary vectors in the set, e.g., the first
(U) and the second (V) vectors, assumming they are all unit
vectors. Normalize them if they aren't.

2. Next compute the cross product N = U x V. This gives you
a normal vector N pointing ONE side of the plane.

3. Take a cross product W = N x U. Now you have {U,W} which
is a orthonormal basis vectors of the plane. In other word,
Span(U,V) = Span(U,W), <U,W>=0, |U|=1, |W|=1.

4. Compute the angle as of any vector Z (in the plane as
following):

theta = atan2(<W.Z>,<U.Z>) % <- Do not change U or W

This gives you ONE consistent way to define angle (only for
vectors belong to the plane).

PS: In a more abstract way, you can also accomplish steps
1->3 by using Gram-Smidth orthogonalization, or QR (help qr).

Bruno

Bruno Luong

unread,
Dec 29, 2007, 4:46:12 AM12/29/07
to
"Bruno Luong" <b.l...@fogale.fr> wrote in message
<fl539d$np9$1...@fred.mathworks.com>...

U=[1 0 0]';
V=[1 0 1]'; % example above

[Q R]=qr([U V],0);
angle=@(v) atan2(dot(Q(:,2),v),dot(Q(:,1),v));

>> angle(U)

0

>> angle(V)

-0.7854

>> angle([1 0 -1])

0.7854

Bruno

Uzair Siddiqui

unread,
Apr 12, 2009, 1:03:01 PM4/12/09
to
Hi

I am just stuck in calculating angle between two points in Flash.

I am using this

angle =Math.abs(Math.atan2(x-x2,y-y2) * 180/Math.PI) ;

But I am getting the angles between 0-180 instead of 0-360.

Can you please help.

I need it badly.

Thanks

Roger Stafford

unread,
Apr 12, 2009, 3:35:01 PM4/12/09
to
"Uzair Siddiqui" <uz...@meragsm.com> wrote in message <grt6s5$2hh$1...@fred.mathworks.com>...

> I am just stuck in calculating angle between two points in Flash.
> I am using this
> angle =Math.abs(Math.atan2(x-x2,y-y2) * 180/Math.PI) ;
> But I am getting the angles between 0-180 instead of 0-360.

When you say "angle between two points", I assume here you mean the angle measured counterclockwise from the positive x-axis around to the vector pointing from point P2 = (x2,y2) to point P = (x,y), creating an angle anywhere from 0 to 2*pi radians or 360 degrees. Is that what you mean?

If so, it can be obtained in degrees with matlab by

angle = 180/pi*mod(atan2(y-y2,x-x2),2*pi);

which lies between 0 and 360 degrees. (I presume this formula remains valid in Flash.)

In your formula the arguments x-x2 and y-y2 are interchanged from this and the answer would lie between -180 and +180 without the 'mod' operation.

Roger Stafford

Uzair Siddiqui

unread,
Apr 13, 2009, 12:16:01 AM4/13/09
to
Thanks A Lot Roger

But What is "mod" function doing in Matlab ?

I hope it just return the remainder after division ?

Another Issue i am facing is that the result is clockwise, but i want anticlockwise angle.

Thanks

"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <grtfp5$oal$1...@fred.mathworks.com>...

Roger Stafford

unread,
Apr 13, 2009, 1:03:34 AM4/13/09
to
"Uzair Siddiqui" <uz...@meragsm.com> wrote in message <gruea1$nep$1...@fred.mathworks.com>...

> But What is "mod" function doing in Matlab ?
> I hope it just return the remainder after division ?
> Another Issue i am facing is that the result is clockwise, but i want anticlockwise angle.

No, you are mistaken, Uzair. The formula I gave you gives the counterclockwise angle, provided of course that the x-y axes are oriented in the conventional manner with the positive y-axis being ninety degrees counterclockwise from the positive x-axis. Try it out and see.

For example, let P = (x,y) = (1,1) and P2 = (x2,y2) = (0,0). The vector from P2 to P is clearly rotated 45 degrees counterclockwise from the x-axis toward the y-axis. The result of the formula is also 45 degrees.

For angles from 'atan2' between 0 and pi radians, the 'mod' operator here leaves them unchanged, but those from -pi to 0 have 2*pi added to place them in the range from pi to 2*pi, as per your request. In degrees that means the answer will range from 0 to 360 degrees.

Roger Stafford

Uzair Siddiqui

unread,
Apr 13, 2009, 3:17:02 AM4/13/09
to
Thanks again Roger.

What I am doing is that i am adding 2*Math.PI to the angle if it is negative.

In this way I am getting the 0-360 angle but it is clockwise.

Can you please explain the mod function, or provide an alternative to this in c++ or java, as that will be more undestandable to me.

Regards
Uzair
Pakistan

Cato

unread,
Oct 23, 2009, 1:03:04 PM10/23/09
to
Thank you very much for posting these messages, Mr. Stafford. These definitely helped!!

"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <grtfp5$oal$1...@fred.mathworks.com>...

duachuot Son

unread,
Jan 10, 2010, 1:21:17 PM1/10/10
to
Hi Roger,

Could you please explaing to me why using atan2 for the angle from positive x-axix to this coordinate (cosine,sine) is the answer?

I believe it has something to do with the unit circle but can't figure it out. In my understanding, the cosine will still compute the small angle. Suppose sine will do the same too.

Thanks a lot,
Son.

Benjamin McCrite

unread,
Feb 23, 2010, 7:41:05 PM2/23/10
to
Greg Heath <he...@alumni.brown.edu> wrote in message <1184052626.3...@n2g2000hse.googlegroups.com>...

> On Jul 9, 5:16 pm, "y Mehta" <mehtayogesh@gmail.(DOT).com> wrote:
> > How do I find the angle between two unit vectors a and b? I know I
> > can find cosine theta by the following formula:
> >
> > theta = acos(dot(a,b));
> >
>
> Invalid since it is possible that abs(dot(a,b)) > 1.
>
> costheta = dot(a,b)/(norm(a)*norm(b));
> theta = acos(costheta);
>
> will give you the anser in the interval [0,pi].

>
> > However, how do I know whether the angle is
> > actually theta, or -theta or pi-theta or pi+theta??
>
> Angles between vectors only lie in the interval [0,pi].

>
> > Notice that the vectors are in three dimension (3d).
>
> Dimensionality of the original space is irrelevant. As long as
> norm(a)*norm(b) > 0, the vectors uniquely define a 2-d space when
> dot(a,b) ~= 0 and a unique 1-d space otherwise.
>
> Hope this helps.
>
> Greg
>


Can you tell me what norm(),cross() and dot() do?

Nathan

unread,
Feb 23, 2010, 7:46:13 PM2/23/10
to
On Feb 23, 4:41 pm, "Benjamin McCrite" <dragonmast...@hotmail.com>
wrote:
>  Greg Heath <he...@alumni.brown.edu> wrote in message <1184052626.324470.175...@n2g2000hse.googlegroups.com>...

Can you read the documentation?
Norm:
The norm of a matrix is a scalar that gives some measure of the
magnitude of the elements of the matrix. The norm function calculates
several different types of matrix norms:

n = norm(A) returns the largest singular value of A, max(svd(A)).

n = norm(A,p) returns a different kind of norm, depending on the value
of p.
...


Cross:
C = cross(A,B) returns the cross product of the vectors A and B. That
is, C = A x B. A and B must be 3-element vectors. If A and B are
multidimensional arrays, cross returns the cross product of A and B
along the first dimension of length 3.

C = cross(A,B,dim) where A and B are multidimensional arrays, returns
the cross product of A and B in dimension dim. A and B must have the
same size, and both size(A,dim) and size(B,dim) must be 3.
...


Dot:
C = dot(A,B) returns the scalar product of the vectors A and B. A and
B must be vectors of the same length. When A and B are both column
vectors, dot(A,B) is the same as A'*B.

For multidimensional arrays A and B, dot returns the scalar product
along the first non-singleton dimension of A and B. A and B must have
the same size.

C = dot(A,B,dim) returns the scalar product of A and B in the
dimension dim.
...


Before asking what functions do, try to read and understand the
documentation for them. To view the documentation, you can type:
doc FUNCTIONNAME

Where, in this case, FUNCTIONNAME is either cross, dot, or norm

-Nathan

Jorian

unread,
Mar 7, 2010, 5:53:05 AM3/7/10
to
"salih tuna" <sali...@gmail.com> wrote in message <fjlrpl$gii$1...@fred.mathworks.com>...

> Hi,
> thanks a lot for your reply. yes they are in 2d, sorry i
> forgot to mention.
> i tried to apply the formula but i am getting wrong result.
> for example i want to calculate the angle between a = [1 1]
> and b = [0 -1] which is 225 degrees. with this formulae i
> got 243.4. i couldn't see where i am doing the mistake.
> thanks a lot in advance
> salih
>
> http://www.musicpa.com

Thanks!
Best regards, Jorian Seokaner!

http://www.mathworks.com/matlabcentral/newsreader/author/126323
>

Beho nashed

unread,
Jun 16, 2010, 7:43:04 PM6/16/10
to
Nathan <ngre...@gmail.com> wrote in message <8db784bf-a96e-431b...@o16g2000prh.googlegroups.com>...

> On Feb 23, 4:41 pm, "Benjamin McCrite" <dragonmast...@hotmail.com>
> wrote:
> >  Greg Heath <he...@alumni.brown.edu> wrote in message <1184052626.324470.175...@n2g2000hse.googlegroups.com>...

Hello Nathan,
I am trying to calculate the angle between two lines, I found this topic, and I have a quick question.
Here's my code:
I = imread('angle.jpg');
figure, imshow(I);
[xp, yp] = ginput;
line(xp,yp,'color',[0 1 0]);
cal_angle = atan2(norm(cross(xp,yp)),dot(xp,yp))
cal_angle2 = acosd(dot(xp,yp)/(norm(xp)*norm(yp)))

I found those two equations online, but I don't think they're right. the first one should be right, I remember it from calculus!

I select three points, get two lines. the angle should be greater than 90, but it always comes smaller than 90!!!
I am not sure, what am I doing wrong here?

Thanks

Beho nashed

unread,
Jun 16, 2010, 7:43:04 PM6/16/10
to
> On Feb 23, 4:41 pm, "Benjamin McCrite" <dragonmast...@hotmail.com>
> wrote:
> >  Greg Heath <he...@alumni.brown.edu> wrote in message <1184052626.324470.175...@n2g2000hse.googlegroups.com>...

Hello Nathan,

Roger Stafford

unread,
Jun 16, 2010, 8:47:03 PM6/16/10
to
"Beho nashed" <beh...@yahoo.com> wrote in message <hvbni8$s0h$1...@fred.mathworks.com>...

> I am trying to calculate the angle between two lines, I found this topic, and I have a quick question.
> Here's my code:
> I = imread('angle.jpg');
> figure, imshow(I);
> [xp, yp] = ginput;
> line(xp,yp,'color',[0 1 0]);
> cal_angle = atan2(norm(cross(xp,yp)),dot(xp,yp))
> cal_angle2 = acosd(dot(xp,yp)/(norm(xp)*norm(yp)))
>
> I found those two equations online, but I don't think they're right. the first one should be right, I remember it from calculus!
>
> I select three points, get two lines. the angle should be greater than 90, but it always comes smaller than 90!!!
> I am not sure, what am I doing wrong here?
>
> Thanks
- - - - - - - - - -
Based on your statement, "I select three points", it looks as though you are entering three quantities each for xp and yp. Unfortunately the 'cross' function which requires vectors with three components interprets each of these as a three-dimensional space vector and not three points in two-dimensional space. The same holds for 'dot' in this case. That means both your angles are wrong.

If you have three points P1 = (x1,y1), P2 = (x2,y2), and P3 = (x3,y3) in two dimensional space, the inner angle at P1 between lines P2P1 and P3P1 is given by

atan2(abs(det([x1,x2,x3;y1,y2,y3;1,1,1])),(x2-x1)*(x3-x1)+(y2-y1)*(y3-y1))

The angle from atan2 is given in radians.

Roger Stafford

Beho nashed

unread,
Jun 16, 2010, 9:00:23 PM6/16/10
to
Hello Roger,
Thanks, so to use this equation, I should change my code to :
[x,y] = ginput;

angle = atan2(abs(det([x(1),x(2),x(3);y(1),y(2),y(3);1,1,1])),(x(2)-x(1))*(x(3)-x(1))+(y(2)-y(1))*(y(3)-y(1)))

I am not sure, I meant x(1) so it will use first value in array x, am I right?

Thanks,

Roger Stafford

unread,
Jun 16, 2010, 10:55:10 PM6/16/10
to
"Beho nashed" <beh...@yahoo.com> wrote in message <hvbs37$a30$1...@fred.mathworks.com>...
- - - - - - - - -
Yes, that looks right if you make sure to enter the vertex of the angle you are finding first so that it goes into P1 = [x(1),y(1)], then followed by the other two points on the two respective lines.

For brevity you can write

P1 = [x(1),y(1)]; % The point at the angle vertex
P2 = [x(2),y(2)];
P3 = [x(3),y(3)];

ang = atan2(abs(det(P2-P1;P3-P1])),dot(P2-P1,P3-P1));

It will give you the same answer (in radians.)

Don't use the word 'angle' for your angle variable. It is a reserved word in matlab and the confusion could cause errors in your program when you least expect it.

Roger Stafford

Beho nashed

unread,
Jun 17, 2010, 9:49:05 PM6/17/10
to
"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <hvc2qe$59b$1...@fred.mathworks.com>...

> "Beho nashed" <beh...@yahoo.com> wrote in message <hvbs37$a30$1...@fred.mathworks.com>...
> > Hello Roger,
> > Thanks, so to use this equation, I should change my code to :
> > [x,y] = ginput;
> >
> > angle = atan2(abs(det([x(1),x(2),x(3);y(1),y(2),y(3);1,1,1])),(x(2)-x(1))*(x(3)-x(1))+(y(2)-y(1))*(y(3)-y(1)))
> >
> > I am not sure, I meant x(1) so it will use first value in array x, am I right?
> >
> > Thanks,
> - - - - - - - - -

Hello Roger,
I keep selecting points for an angle bigger than 90 degree, but the program is giving me an angle less than 90 deg!!!

http://drop.io/rlv072i (image 3, called test)
I pick three points, two points on the surface (on the left side) and the third on the slope ( the white one), making two lines with an angle bigger than 90 deg!

Thanks in advance Roger

Roger Stafford

unread,
Jun 18, 2010, 12:38:03 AM6/18/10
to
"Beho nashed" <beh...@yahoo.com> wrote in message <hvejah$ab6$1...@fred.mathworks.com>...

> Hello Roger,
> I keep selecting points for an angle bigger than 90 degree, but the program is giving me an angle less than 90 deg!!!
> .......

There must be something amiss, either with the way you are selecting your points or the way their coordinates are being collected. I have done a copy and paste on the three different forms of the formulas we have discussed and after supplying a missing left bracket in the last one, (sorry about that) they all give the same answer which can be anywhere between zero and pi radians, or in degrees, anywhere between 0 and 180 degrees. I illustrate with one example here which yields the correct answer of 135 degrees (after multiplying by 180/pi to transform from radians to degrees) for all three formulas.

P1 = [2,1];
P2 = [6,3];
P3 = [-7,4];
x = [P1(1);P2(1);P3(1)];
y = [P1(2);P2(2);P3(2)];
x1 = x(1); y1 = y(1);
x2 = x(2); y2 = y(2);
x3 = x(3); y3 = y(3);
ang1 = atan2(abs(det([x1,x2,x3;y1,y2,y3;1,1,1])), ...
(x2-x1)*(x3-x1)+(y2-y1)*(y3-y1));
ang2 = atan2(abs(det([x(1),x(2),x(3);y(1),y(2),y(3);1,1,1])), ...
(x(2)-x(1))*(x(3)-x(1))+(y(2)-y(1))*(y(3)-y(1)));
ang3 = atan2(abs(det([P2-P1;P3-P1])),dot(P2-P1,P3-P1));

180/pi*[ang1;ang2;ang3] =

135
135
135

Roger Stafford

Beho nashed

unread,
Jun 18, 2010, 10:41:07 AM6/18/10
to
"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <hvet7b$b6c$1...@fred.mathworks.com>...

> "Beho nashed" <beh...@yahoo.com> wrote in message <hvejah$ab6$1...@fred.mathworks.com>...
> > Hello Roger,
> > I keep selecting points for an angle bigger than 90 degree, but the program is giving me an angle less than 90 deg!!!


Hello Roger,
I actually noticed the bracket and fixed it. I just noticed something in the image displayed. the Y-axis starts from the top!!!

I tried to use set(gca,'ydir','normal') , but it flips the picture and the axis, not just the axis. I am not sure how to flip the axis only, I believe that's the problem.

Thanks

us

unread,
Jun 18, 2010, 11:55:07 AM6/18/10
to
"Beho nashed" <beh...@yahoo.com> wrote in message <hvg0i3$khr$1...@fred.mathworks.com>...

one of the solutions

axis image;

us

Beho

unread,
Jun 18, 2010, 12:48:48 PM6/18/10
to
can I just use this (2 points)

I = imread('angle.jpg');
figure, imshow(I);

axis image;
[x, y] = ginput;
line(x,y,'color',[0 1 0]);

ang1= 180 - subspace(x,y)*180/pi

Roger Stafford

unread,
Jun 18, 2010, 6:51:05 PM6/18/10
to
Beho <newpara...@gmail.com> wrote in message <e615968b-18d6-489f...@g19g2000yqc.googlegroups.com>...

No, I don't think that would work for what you are doing. The angle given by subspace is never greater than 90 degrees (pi/2,) so if you subtract it from 180, it will never be less than 90. I understood that you wanted the angle between two (directed) vectors which can range anywhere between 0 and 180.

If you only want the smaller of the two angles between two lines without regard to direction along the lines and if both lines pass through the origin, then subspace, (without the subtraction from 180,) would indeed give you that answer.

Note: As I pointed out in another thread a week ago, there is an erroneous statement made in MathWorks' description of subspace. They state that, "If A and B are column vectors of unit length, this is the same as acos(A'*B)." It would actually be acos(abs(A'*B)), and that is why the angle from subspace can never be greater than 90 degrees (pi/2.)

Roger Stafford

Beho nashed

unread,
Jun 19, 2010, 12:05:22 PM6/19/10
to
"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <hvgt8p$ss7$1...@fred.mathworks.com>...

> Beho <newpara...@gmail.com> wrote in message <e615968b-18d6-489f...@g19g2000yqc.googlegroups.com>...
> > can I just use this (2 points)
> >

Hello Roger,
so how to change the code just to measure the angle, between the two lines.
should I use two points.

I used subspace, I selected two points (giving an approximate 45 deg), but it gave me 4 degree and sometimes 14 deg, I am not gonna use this one.

I am not sure Roger how to calculate the angle? is the y-axis messing up the angle?
Thanks

Roger Stafford

unread,
Jun 19, 2010, 1:40:22 PM6/19/10
to
"Beho nashed" <beh...@yahoo.com> wrote in message <hvips2$nuh$1...@fred.mathworks.com>...

> Hello Roger,
> so how to change the code just to measure the angle, between the two lines.
> should I use two points.
> I used subspace, I selected two points (giving an approximate 45 deg), but it gave me 4 degree and sometimes 14 deg, I am not gonna use this one.
> I am not sure Roger how to calculate the angle? is the y-axis messing up the angle?
> Thanks
- - - - - - - - - -
When speaking of the angle between two lines it is necessary to distinguish between two possible meanings. If the lines are "undirected", meaning that there is no preferred direction along either line, then there are two angles between the lines to be considered, one being the supplement of the other, and their sum is 180 degrees (or pi radians.) Usually the smaller of the two is chosen as being the defined angle between the lines, and that is the one given by matlab's 'subspace' function for two lines through the origin. Such an angle cannot exceed 90 degrees by definition.

On the other hand there is the concept of the angle between two directed lines, meaning that there is a preferred "positive" direction along each line. This is equivalent to the notion of the angle between two vectors which have a common base point. Such an angle can range from 0 to 180 degrees. It is this latter kind of angle that I have been giving the formulas for. Matlab's 'atan2' function is actually capable of producing angles anywhere between minus pi and plus pi radians, but in all these formulas, the first argument was always non-negative, so that restricts the angle to the first two quadrants, and 'atan2' can then only produce results for these that range from zero to pi radians (0 to 180 in degrees.)

In neither kind of situation can one find the angle with only two points! You will always need either two points on each line to establish a direction for each one, or else the point of intersection of the two lines and one other point on each line. If both the two lines pass through the coordinate origin, then that point of intersection is the origin and only two other points on the lines are required.

If the lines are considered as directed, then on each line the coordinates of the point less far out in the positive direction are subtracted from those of the other point farther out, and this establishes the components of the two vectors needed to determine the angle between the directed lines.

I hope this finally winds up this thread about finding the "angle between two vectors" which has now gone on for forty-eight articles and stretched over a span of almost three years. That is quite enough in my opinion for such an elementary concept.

Roger Stafford

Bard Romstad

unread,
Jul 17, 2010, 2:50:04 PM7/17/10
to
"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <fl3moi$pvc$1...@fred.mathworks.com>...
> "baris kazar" <mbkazar...@gmail.com> wrote in message <fl377q$4ip
> $1...@fred.mathworks.com>...
> > Hi,-
> > how can we generalize this to 3-D vectors? Think of a
> > plane on 3-D space and you have vectors on this plane. I
> > wanna know the angle between 2 vectors in the range 0-2pi.
> > or at least -pi to pi. I have 3 vectors. One (First)
> > vector is the same all the time. I wanna know the relative
> > positions of the other two vector wrt the firsy one. Thus,
> > i need angles in the range 0 to 2pi or -pi to pi.
> > Thanks in advance
> ---------
> As Bruno has pointed out, the angle between two three-dimensional vectors
> depends on which sense one gives to a vector orthogonal to their plane. It
> isn't clear what you meant by, "the relative positions of the other two vector
> wrt the firsy one." The vector cross product of the second two vectors will be
> a vector orthogonal to their plane. Perhaps you mean that the angle between
> them is to be considered positive if this cross product lies on the same side
> of the plane as this first vector, and negative otherwise. If that is the case,
> then let your first, second, and third vectors be designated as x, y, and z,
> respectively. A matlab formula for calculating the angle between y and z will
> then be:
>
> c = cross(y,z);
> angleyz = sign(dot(x,c))*atan2(norm(c),dot(y,z));
>
> The value of 'angleyz' will range from -pi to +pi. If you want it to range from
> 0 to 2*pi, then apply the 'mod' function as I did on Dec. 11 in this thread.
>
> Roger Stafford
>

This will fail if all three vectors x, y and z lie on the same plane because then dot(x,c)=0 (and sign(0)=0 -> angleyz = 0).
Example:
x = [1 0 1];
y = [0 1 1];
z = [0.5 0.5 1];
x=x/norm(x);y=y/norm(y);z=z/norm(z);
c = cross(y,z);
angleyz = sign(dot(x,c))*atan2(norm(c),dot(y,z))

Any suggestions?

BÃ¥rd Romstad

Roger Stafford

unread,
Jul 17, 2010, 5:31:03 PM7/17/10
to
"Bard Romstad" <this.is.not.a...@gmail.com> wrote in message <i1su0s$deu$1...@fred.mathworks.com>...
- - - - - - - - - -
Well of course it fails, based as it is on a desperate guess as to what Baris Kazar meant when he said (back on December 28, 2007) "the relative positions of the other two vector wrt the firsy one"! This was an attempt on my part to interpret his statement as indicating that the first vector establishes which side of the plane containing the second two vectors is to be considered as its "positive" side. If that first vector lies in this plane, then of course it fails to do so.

With three 3D vectors all lying in a plane through their origin, even if one of them is regarded as some sort of reference, there is no inherent "clockwise" or "counterclockwise" sense to angles in that plane. Only some reference direction outside the plane or else a pair of "standard" vectors within the plane can do that. When we say "clockwise" it is said from the point of view of a person seeing a clock from outside the plane of the clock hands from the usual side of the clock. If a transparent clock is viewed from its rear, what was the clockwise direction now becomes the counterclockwise direction (if the backward numerals are ignored.) The famous "right-hand rule" depends on one's right-hand thumb lying outside the plane of one's curled finger directions.

Bard, if you want a formula for the angle between Baris Kazar's second two vectors ranging from 0 to 2*pi, please explain to me your idea of what you think he meant by the above quotation given that the first vector lies in their plane.

Roger Stafford

Bard Romstad

unread,
Jul 18, 2010, 6:55:04 AM7/18/10
to
"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <i1t7en$gvq$1...@fred.mathworks.com>...

Hi Roger,
Giving it a second look I'm not quite certain what Baris ment after all, but what I am trying to find is how to calculate the signed angle (-pi to pi) between two vectors, A and B, projected onto the vertical plane passing through vector C, viewed from the direction defined by cross(C,[0 0 1]).
To clarify (or confuse):
In my specific problem A and B are surface normals of two neighbouring patches on a 2.5D topographic surface (no caves/overhangs -> normals are always pointing upwards). I want to investigate the convexity of the topographic surface along a given direction (defined by the horizontal component of C). My idea was to do this by finding the angle between A and B (relative to C).

Bard Romstad

unread,
Jul 18, 2010, 10:36:03 AM7/18/10
to
> Hi Roger,
> Giving it a second look I'm not quite certain what Baris ment after all, but what I am trying to find is how to calculate the signed angle (-pi to pi) between two vectors, A and B, projected onto the vertical plane passing through vector C, viewed from the direction defined by cross(C,[0 0 1]).
> To clarify (or confuse):
> In my specific problem A and B are surface normals of two neighbouring patches on a 2.5D topographic surface (no caves/overhangs -> normals are always pointing upwards). I want to investigate the convexity of the topographic surface along a given direction (defined by the horizontal component of C). My idea was to do this by finding the angle between A and B (relative to C).

Having thought a little more about this I guess a more general formulation of my question is how to find the signed angle (-pi to pi) between two vectors, A and B, projected onto the plane defined by a normal vector N (which in the specific case above was cross(C,[0 0 1])), viewed from the direction of N.

BÃ¥rd

Roger Stafford

unread,
Jul 18, 2010, 1:13:05 PM7/18/10
to
"Bard Romstad" <this.is.not.a...@gmail.com> wrote in message <i1v3gj$8rh$1...@fred.mathworks.com>...

> Having thought a little more about this I guess a more general formulation of my question is how to find the signed angle (-pi to pi) between two vectors, A and B, projected onto the plane defined by a normal vector N (which in the specific case above was cross(C,[0 0 1])), viewed from the direction of N.
>
> BÃ¥rd
- - - - - - - - - - -
Yes, that makes sense. I presume when you say, "viewed from the direction of N", you mean in accordance with the right-hand rule: if your right-hand thumb points along the direction of N, then your fingers curl in the direction of positive angle change. And when you say, "signed angle between A and B" you mean the angle measured from the projection of A toward the projection of B but restricted to the interval -pi to +pi.

That can be done this way:

N = N/norm(N); % Make N a unit vector
ang = atan2(dot(cross(A,B),N),dot(cross(A,N),cross(B,N)));

Note that this will fail if either A or B is parallel to N, as you would expect, since the projection of that respective vector onto the plane would then be zero and therefore the angle would be undefined.

Roger Stafford

Bard R.

unread,
Jul 18, 2010, 2:38:03 PM7/18/10
to
"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <i1vcn1$s7p$1...@fred.mathworks.com>...

This is exactly what I was looking for. And so much more compact than the solution I had put together during the day. It works if A and B are opposite (I had to do an extra check for that as well) and for my application N is by definition never parallell to neither A nor B.
Thanx a lot!

BÃ¥rd

Roger Stafford

unread,
Jul 18, 2010, 3:52:03 PM7/18/10
to
"Bard R." <this.is.not.a...@gmail.com> wrote in message <i1vhmb$1rq$1...@fred.mathworks.com>...

> This is exactly what I was looking for. And so much more compact than the solution I had put together during the day. It works if A and B are opposite (I had to do an extra check for that as well) and for my application N is by definition never parallell to neither A nor B.
> Thanx a lot!
> BÃ¥rd
- - - - - - - - - - - -
Well, if A and B, or even their projections, are in opposite directions, the outcome can suddenly flip from one extreme to the other depending on rounding. A roundoff one way gets +pi as a result and in the other direction flips the answer over to -pi. I don't see any good way out of that problem. It is more or less inherent in the nature of numerical computation of angles. A digital computer cannot even compute the exact value of pi itself.

Roger Stafford

Loren_Shure

unread,
Jul 19, 2010, 8:21:39 AM7/19/10
to

"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in
message news:i1vm13$ok8$1...@fred.mathworks.com...

Have you checked out the function subspace:
http://www.mathworks.com/access/helpdesk/help/techdoc/ref/subspace.html ?


--
Loren
http://blogs.mathworks.com/loren/
http://matlabwiki.mathworks.com/MATLAB_FAQ

us

unread,
Jul 19, 2010, 8:38:04 AM7/19/10
to
"Loren_Shure" <loren...@mathworks.com> wrote in message <i21g0k$ker$1...@fred.mathworks.com>...

>
> "Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in
> message news:i1vm13$ok8$1...@fred.mathworks.com...
> > "Bard R." <this.is.not.a...@gmail.com> wrote in message
> > <i1vhmb$1rq$1...@fred.mathworks.com>...
> >> This is exactly what I was looking for. And so much more compact than the
> >> solution I had put together during the day. It works if A and B are
> >> opposite (I had to do an extra check for that as well) and for my
> >> application N is by definition never parallell to neither A nor B.
> >> Thanx a lot!
> >> B&#52293;rd

> > - - - - - - - - - - - -
> > Well, if A and B, or even their projections, are in opposite directions,
> > the outcome can suddenly flip from one extreme to the other depending on
> > rounding. A roundoff one way gets +pi as a result and in the other
> > direction flips the answer over to -pi. I don't see any good way out of
> > that problem. It is more or less inherent in the nature of numerical
> > computation of angles. A digital computer cannot even compute the exact
> > value of pi itself.
> >
> > Roger Stafford
>
> Have you checked out the function subspace:
> http://www.mathworks.com/access/helpdesk/help/techdoc/ref/subspace.html ?
>
>
> --
> Loren
> http://blogs.mathworks.com/loren/
> http://matlabwiki.mathworks.com/MATLAB_FAQ

dearest loren
if you carefully wade through this thread you'll find out that it has been discussed at length, already...

:-)
urs

Roger Stafford

unread,
Jul 19, 2010, 1:19:04 PM7/19/10
to
"Loren_Shure" <loren...@mathworks.com> wrote in message <i21g0k$ker$1...@fred.mathworks.com>...
- - - - - - - - -
Yes, Loren, as Urs has said, that was discussed in article #46 of this overly-long thread. The person proposing to use subspace was seeking an angle that ranges from 0 to pi (180 deg) as in the inner angle in triangles, but subspace would not give an angle beyond pi/2 in this case. For example

a = subspace([1;0],[-1;1]) ---> 1/4*pi

whereas

a = acos([1;0],[-1;1]) --> 3/4*pi

This reminds me. As I pointed out in that #46 article, Mathworks' documents are still in error in claiming about subspace "If A and B are column vectors of unit length, this is the same as acos(A'*B)." This error was present in my manual for system 4a back in 1994 and it still persists to this day in their most recent documentation. It should read acos(abs(A'*B)). Have you any influence with the documentation department to get them to finally make a correction on this misleading statement?

Roger Stafford

Loren Shure

unread,
Jul 20, 2010, 7:54:36 AM7/20/10
to

"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in
message news:i221e8$3du$1...@fred.mathworks.com...

Roger-

Will enter a request to update the doc...

Robert Phillips

unread,
Dec 7, 2010, 12:27:18 PM12/7/10
to
Roger,


This thread is very interesting! It directly applies to a problem I'm tackling, as you may have read in other threads.

I try to calculate cosine values using the formula

cos(theta) = (dot(A,B)) / (|A|*|B|),

but for A = [M-by-3] and B = [1-by-3] & a=|A| b=|B|

% Calculate cosines of angles between a_E & r_Es vectors.
cos(theta) = cellfun(@sum,...
(mat2cell((A(:,1:3).*(repmat(B(i,:),...
size(A(:,1:3),1),1))),...
ones(1,size(A(:,1:3),1)),3)))./(a*b);

And I get cosine values ranging between 0 and +/- 2.667, for B lines parallel to A.
In fact, it's desirable if B is parallel to A.

How might you suggest calculating the cosine value, or even calculating the angle between, A=[M-by-3] & B=[1-by-3]? (without loops)

Geant Bepi

unread,
Dec 17, 2010, 10:51:05 AM12/17/10
to
Hey guys!

sorry for posting something irrelevant to the topic being discussed here..

but I need some help!

I invite the brains here to look at my simple problem mentioned below and help me with some tips;
link: http://www.mathworks.com/matlabcentral/newsreader/view_thread/297252#804997

appreciate any knowledge you'd like to share on the matter
thanks heaps!

Marwan N

unread,
Mar 10, 2011, 2:04:05 AM3/10/11
to
hey guys,

I went thro the codes u all gave several times....all are different ways for the same pupose....which finally gave me a head spin after all those cods in my head. As a simple conclusion can someone answer me the following:

1. how do we calculate the angle (consider both the obtuse and acute angle) between two vectors (consider that they intersect at origin or in other words, they originate from origin)

2.the vectors start at the origin and terminate at the points X=[coresponding coeff of i j k] and Y=[corresponding coeff of i j k]

3.the results (obtuse and acute angle) should lie between 0 and pi.

any bright ideas anyone??

Bruno Luong

unread,
Mar 10, 2011, 2:56:04 AM3/10/11
to
"Marwan N" wrote in message <il9t55$en6$1...@fred.mathworks.com>...

>> a=randn(2,1)

a =

1.4897
1.4090

>> b=randn(2,1)

b =

1.4172
0.6715

% Pad 0 to extend in 3D if needed
>> a(3)=0
>> b(3)=0

% Roger method

>> angle = atan2(norm(cross(a,b)),dot(a,b))

angle =

0.3151

angle will be [0,pi] since norm(cross(a,b)) >= 0.

Bruno

Loren Shure

unread,
Mar 10, 2011, 7:21:44 AM3/10/11
to

"Marwan N" <munn...@gmail.com> wrote in message
news:il9t55$en6$1...@fred.mathworks.com...

Will the subspace function do what you want?
http://www.mathworks.com/help/techdoc/ref/subspace.html

--
Loren
http://blogs.mathworks.com/loren/
http://www.mathworks.com/matlabcentral/

Bruno Luong

unread,
Mar 10, 2011, 8:38:05 AM3/10/11
to
"Loren Shure" <loren...@mathworks.com> wrote in message <ilafo2$nnp$1...@fred.mathworks.com>...

subspace() will always reduce the resultant angle between [0,pi/2]. I'm not sure this is appropriate for geometry computation.

Bruno

Marwan N

unread,
Mar 10, 2011, 9:14:05 AM3/10/11
to
thnks Bruno.....finally the thread has conclusion.

philippa

unread,
Aug 16, 2011, 7:17:31 AM8/16/11
to
Wondering if anyone can please help me with yet another problem calculating angles in matlab!

Ill set the scene:
I am simulating erosion on volcano slopes. I have a bathymetry dataset for a volcano - a matrix of land heights in the form a grid. Suppose for simplicity the grid is 100km x 100km and i have a measurement of land height (z) at every 1km. So we are in 3D.

I want to calculate the angle of the volcano sides - so essentially I will have a matrix of angles in which the slope angle is calculated between a point and the point directly above it (so looking from the bottom of the volcano towards the peak). Im struggling because on the East slope, the peak will be to the West, whereas at the South, it will be to the North. I thus wonder whether I will need to calculate the angles using vertical cross sections of the volcano and rotate the matrix through 360 degrees.

Some help would be greatly appreciated as honestly i dont know where to start! and let me know if what ive said doesnt make sense!
Thank you!!

Roger Stafford

unread,
Aug 16, 2011, 12:36:14 PM8/16/11
to
"philippa" wrote in message <j2djkb$j0o$1...@newscl01ah.mathworks.com>...
- - - - - - - -
You can use the matlab 'gradient' function with a two-dimensional input. Be sure to read its documentation. The angle of steepest gradient you seek can be found as the arc tangent of the gradient magnitude:

[Fx,Fy] = gradient(Z);
ang = atan(sqrt(Fx.^2+Fy.^2));

where Fx and Fy are the two components of the gradient.

In case you need it the azimuth angle of steepest gradient measured counterclockwise from the x-axis is given by

azi = atan2(Fy,Fx);

These angles are both in radian measure.

I believe on the boundaries the gradient function is only a first order approximation while in the interior it is second order. For higher order approximations there are undoubtedly some to be found in the file exchange.

Roger Stafford

Roger Stafford

unread,
Aug 16, 2011, 12:46:26 PM8/16/11
to
"Roger Stafford" wrote in message <j2e69u$njg$1...@newscl01ah.mathworks.com>...

> You can use the matlab 'gradient' function with a two-dimensional input. Be sure to read its documentation. The angle of steepest gradient you seek can be found as the arc tangent of the gradient magnitude:
>
> [Fx,Fy] = gradient(Z);
> ang = atan(sqrt(Fx.^2+Fy.^2));
>
> where Fx and Fy are the two components of the gradient.
>
> In case you need it the azimuth angle of steepest gradient measured counterclockwise from the x-axis is given by
>
> azi = atan2(Fy,Fx);
>
> These angles are both in radian measure.
>
> I believe on the boundaries the gradient function is only a first order approximation while in the interior it is second order. For higher order approximations there are undoubtedly some to be found in the file exchange.
>
> Roger Stafford
- - - - - - - -
Note: Make sure the units of vertical Z elevation are the same as the horizontal units between adjacent points of Z.

Roger Stafford

Jonathan

unread,
Aug 19, 2011, 6:55:11 PM8/19/11
to
"y Mehta" <mehtayogesh@gmail.(DOT).com> wrote in message <ef5ce...@webcrossing.raydaftYaTP>...
> How do I find the angle between two unit vectors a and b? I know I
> can find cosine theta by the following formula:
>
> theta = acos(dot(a,b));
>
> However, how do I know whether the angle is actually theta, or -theta
> or pi-theta or pi+theta??
>
> Notice that the vectors are in three dimension (3d).
>
> Thanks,
> -YM

You don't need to know the angle between [0,2pi]. All you need is:
angle = acos( dot(a,b) / (norm(a)*norm(b)) );

Then if you want to rotate:
* a towards b: you should rotate a of +'angle' radians around the axis cross(a,b)
* b towards a: you should rotate b of +'angle' radians around the axis cross(b,a)

The cross-product will have the right orientation depending on what you want to do.

Roger Stafford

unread,
Aug 19, 2011, 8:25:09 PM8/19/11
to
"Jonathan " <Johnh...@hotmail.fr> wrote in message <j2mpke$4cu$1...@newscl01ah.mathworks.com>...
- - - - - - - - - - -
Jonathan, this thread was begun over four years ago and has now stretched to no less than 70 articles. Moreover it concerns a very elementary subject in which every conceivable aspect of the original question seems to have been thoroughly explored. Don't you think we ought to let the thread finally come to a peaceful termination?

Roger Stafford

Dylan

unread,
Oct 12, 2011, 2:54:26 PM10/12/11
to
"Roger Stafford" wrote in message <fjm4u4$i8o$1...@fred.mathworks.com>...
> "salih tuna" <sali...@gmail.com> wrote in message <fjlrpl$gii
> $1...@fred.mathworks.com>...
> > Hi,
> > thanks a lot for your reply. yes they are in 2d, sorry i
> > forgot to mention.
> > i tried to apply the formula but i am getting wrong result.
> > for example i want to calculate the angle between a = [1 1]
> > and b = [0 -1] which is 225 degrees. with this formulae i
> > got 243.4. i couldn't see where i am doing the mistake.
> > thanks a lot in advance
> > salih
> >
> > "Roger Stafford" <ellieandr...@mindspring.com.invalid>
> > wrote in message <fjk0tg$jli$1...@fred.mathworks.com>...
> > > angle = mod(atan2(y2-y1,x2-x1),2*pi); % Range: 0 to 2*pi
> --------
> I certainly owe you an apology, Salih. That formula I gave you is very, very
> wrong. I can't imagine what I was thinking about when I wrote it. Chalk it up
> to momentary insanity! :-) The correct computation should be as follows.
>
> Assuming a = [x1,y1] and b = [x2,y2] are two vectors with their bases at the
> origin, the non-negative angle between them measured counterclockwise
> from a to b is given by
>
> angle = mod(atan2(x1*y2-x2*y1,x1*x2+y1*y2),2*pi);
>
> As you can see, this bears a close relationship to the three-dimensional
> formula I wrote last July 10. The quantities, x1*y2-x2*y1 and x1*x2+y1*y2
> are, respectively, the sine and cosine of the counterclockwise angle from
> vector a to vector b, multiplied by the product of their norms - that is, their
> cross product and the dot product restricted to two dimensions. The 'atan2'
> function then gives the angle between them ranging from -pi to +pi, and the
> 'mod' operation changes this so as to range from 0 to 2*pi, as you requested.
>
> Roger Stafford
>
>

Hate to belabor this thread, but I'm not getting the above equation to work. It works for the one test case you mention in a later thread a=(1,1) and b=(0,-1), but not much else. For example a=(0,1) and b=(1,0) gives 180. I can get the angle easily by using atan2(x2,y2) - atan2(x1,y1) but I haven't thought of a clever way to deal with wrapping without using a couple of if-then statements. (I want the answer to fall between -180 and 180)

thanks.

Dylan

unread,
Oct 12, 2011, 3:13:10 PM10/12/11
to
"Dylan" wrote in message <j74np2$m9p$1...@newscl01ah.mathworks.com>...
Now I have to confess that I was using Excel to do this calculation which takes it's inputs as atan2(x,y). Matlab has them switched to atan2(y,x) which seems backward to me, but oh well. Sorry for my confusion.

Bjorn Gustavsson

unread,
Oct 18, 2011, 10:39:26 AM10/18/11
to
"Dylan" wrote in message <j74os6$qcj$1...@newscl01ah.mathworks.com>...
>
[snip]
>
> Now I have to confess that I was using Excel to do this calculation which takes it's inputs
> as atan2(x,y). Matlab has them switched to atan2(y,x) which seems backward to me,
> but oh well. Sorry for my confusion.
>
Well it is not "just" matlab that has them switched. The history of atan2 suggests that if anything it is the other way around:

http://en.wikipedia.org/wiki/Atan2

I think of it as this for a mnemonic: atan(y/x) -> atan2(y,x), just replace the "/" with a ","

See also: man atan2

Sergio

unread,
Feb 16, 2012, 12:25:40 PM2/16/12
to
Very useful!
Thanks :-)

"salih tuna" <sali...@gmail.com> wrote in message <fjmabs$9fh$1...@fred.mathworks.com>...
> Roger hi,
> thanks a lot for your help but i am afraid something is
> still missing. i tried the formulae on the same example of
> a = [1 1]and b = [0 -1] (both passing through origin).
> the answer i got is 315 instead of 225.
> sorry i am taking a lot of your time :)
> thanks

Amit

unread,
Mar 17, 2012, 7:02:17 AM3/17/12
to
"Roger Stafford" wrote in message <hvet7b$b6c$1...@fred.mathworks.com>...
> "Beho nashed" <beh...@yahoo.com> wrote in message <hvejah$ab6$1...@fred.mathworks.com>...
> > Hello Roger,
> > I keep selecting points for an angle bigger than 90 degree, but the program is giving me an angle less than 90 deg!!!
> > .......
>
> There must be something amiss, either with the way you are selecting your points or the way their coordinates are being collected. I have done a copy and paste on the three different forms of the formulas we have discussed and after supplying a missing left bracket in the last one, (sorry about that) they all give the same answer which can be anywhere between zero and pi radians, or in degrees, anywhere between 0 and 180 degrees. I illustrate with one example here which yields the correct answer of 135 degrees (after multiplying by 180/pi to transform from radians to degrees) for all three formulas.
>
> P1 = [2,1];
> P2 = [6,3];
> P3 = [-7,4];
> x = [P1(1);P2(1);P3(1)];
> y = [P1(2);P2(2);P3(2)];
> x1 = x(1); y1 = y(1);
> x2 = x(2); y2 = y(2);
> x3 = x(3); y3 = y(3);
> ang1 = atan2(abs(det([x1,x2,x3;y1,y2,y3;1,1,1])), ...
> (x2-x1)*(x3-x1)+(y2-y1)*(y3-y1));
> ang2 = atan2(abs(det([x(1),x(2),x(3);y(1),y(2),y(3);1,1,1])), ...
> (x(2)-x(1))*(x(3)-x(1))+(y(2)-y(1))*(y(3)-y(1)));
> ang3 = atan2(abs(det([P2-P1;P3-P1])),dot(P2-P1,P3-P1));
>
> 180/pi*[ang1;ang2;ang3] =
>
> 135
> 135
> 135
>
> Roger Stafford

Hello Roger,
I want to find the angle between line1 as vertex-p2 and line2 as vertex-points stored in array either in clockwise or anticlockwise.But did not getting angles with following code:

vertex=[186,130];
p2=[278,155];
x=[87 91 103 175];%x co-ordinates of points
y=[134 104 76 31];%y co-ordinates of points

[r,c]=size(x);
ang=zeros(size(x));

for i=1:c
pt=[x(i),y(i)];
ang(i)=mod(atan2(abs(det([p2-vertex;pt-vertex])),dot(p2-vertex,pt-vertex)),2*pi);
end;

ang=180/pi*ang;
display(ang);

This gives the result as
ang =

162.4839 179.8963 162.1543 111.5426

if these angles are only anticlockwise then pt[175,31] would have angle more than 180 degrees
or if it is clockwise [87,134] would have angle more than 180 degrees.
Please help me with this.
Thanks in advance.

Roger Stafford

unread,
Mar 17, 2012, 7:10:29 PM3/17/12
to
"Amit " <av_pa...@yahoo.com> wrote in message <jk1qvp$492$1...@newscl01ah.mathworks.com>...
> Hello Roger,
> I want to find the angle between line1 as vertex-p2 and line2 as vertex-points stored in array either in clockwise or anticlockwise.But did not getting angles with following code:
>
> vertex=[186,130];
> p2=[278,155];
> x=[87 91 103 175];%x co-ordinates of points
> y=[134 104 76 31];%y co-ordinates of points
>
> [r,c]=size(x);
> ang=zeros(size(x));
>
> for i=1:c
> pt=[x(i),y(i)];
> ang(i)=mod(atan2(abs(det([p2-vertex;pt-vertex])),dot(p2-vertex,pt-vertex)),2*pi);
> end;
>
> ang=180/pi*ang;
> display(ang);
>
> This gives the result as
> ang =
>
> 162.4839 179.8963 162.1543 111.5426
>
> if these angles are only anticlockwise then pt[175,31] would have angle more than 180 degrees
> or if it is clockwise [87,134] would have angle more than 180 degrees.
> Please help me with this.
> Thanks in advance.
- - - - - - - - - -
In two dimensional space there is a difference between, on the one hand finding the angles, say, within a triangle which always lie between 0 and pi radians (0 and 180 degrees), and on the other hand finding the angle between two vectors with a common base starting from one of them and rotating counterclockwise (or sometimes clockwise) until first encountering the other one. The latter gives an angle that is anywhere between 0 and 2*pi radians (0 and 360 degrees), or according to a different convention, between -pi and +pi radians (-180 and +180 degrees.) In using matlab's 'atan2' function properly it is immportant to distinguish between these different meanings.

In your problem if you want to rotate counterclockwise from the vector p2-v (using 'v' instead of 'vertex') until first encountering the vector pt-v, expecting an angle between 0 and 360 degrees, the appropriate formula would be:

ang = mod(atan2(det([p2-v;pt-v]),dot(p2-v,pt-v)),2*pi)*180/pi;

Note that the 'abs' operation is missing here. That only applies if you are seeking results that are restricted to lie between 0 and pi as in the angles of a triangle. The 'mod' operation is necessary here since 'atan2' yields answer between -pi and +pi, so the negative answers need to have 2*pi added to them. If the rotation is counterclockwise from pt-v to p2-v or if it is clockwise from p2-v to pt-v, the two arguments pt-v and p2-v would be reversed in the above formula. If your convention is that going beyond pi radians is regarded as negative rotation, then you would leave out the 'mod' operation.

In the example you gave with

pt = [ 87,134;
91,104;
103, 76;
175, 31];
p2 = [278,155];
v = [186,130];

the formula above for rotating counterclockwise from p2-v to pt-v
would give the four answers:

162.4839 180.1037 197.8457 248.4574

Reversing the arguments (that is, going clockwise or from pt-v to p2-v)
would give:

197.5161 179.8963 162.1543 111.5426

Without the 'mod' operation the counterclockwise from p2-v to pt-v answers would be:

162.4839 -179.8963 -162.1543 -111.5426

Roger Stafford
0 new messages