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
---------------------
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
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
---------------
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
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.
> 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
"y Mehta" <mehtayogesh@gmail.(DOT).com> wrote in message
<ef5ce...@webcrossing.raydaftYaTP>...
"y Mehta" <mehtayogesh@gmail.(DOT).com> wrote in message
<ef5ce...@webcrossing.raydaftYaTP>...
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
"Roger Stafford" <ellieandr...@mindspring.com.invalid>
wrote in message <fjk0tg$jli$1...@fred.mathworks.com>...
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
"Roger Stafford" <ellieandr...@mindspring.com.invalid>
wrote in message <fjm4u4$i8o$1...@fred.mathworks.com>...
Roger Stafford
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
>
> 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
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
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
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
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
Hi Bruno,
i did not say THERE IS.
Best regards,
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,
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
>
> 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
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
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
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
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>...
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
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
"Roger Stafford" <ellieandr...@mindspring.com.invalid> wrote in message <grtfp5$oal$1...@fred.mathworks.com>...
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.
Can you tell me what norm(),cross() and dot() do?
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
Thanks!
Best regards, Jorian Seokaner!
http://www.mathworks.com/matlabcentral/newsreader/author/126323
>
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
Hello Nathan,
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
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,
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
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
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 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
one of the solutions
axis image;
us
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
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
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
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
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
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
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
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
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
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
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
Roger-
Will enter a request to update the doc...
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)
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!
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??
>> 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
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/
subspace() will always reduce the resultant angle between [0,pi/2]. I'm not sure this is appropriate for geometry computation.
Bruno
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!!
[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
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