Reputation: 77
I'm sorry if this question seems a really basic, but I cannot find a good answer online yet.
I'm a little confused with vectors and how to use them in matlab. At the moment I have the following three pair of coordinates (x and y): Person 1, The future location of Person 1 and Person 2. See: The three points in a 2d view
Now I want to calculate the angle between "the vector which goes from person 1 to person 2" and "the vector from person 1 to person 1 future". I've found some matlab functions which could do this with the vectors, but I am not sure I am actually using the right input for each vector.
So now my question is how can I use these coordinates (and the difference between them) to calculate the angle from the image?
Upvotes: 3
Views: 8480
Reputation: 77
Coordinates of person 1,(x1,y1)-future person 1 ,(x11,y11)-person 2(x2,y2).
Consider x11-x1=xa and y11-y1=ya then x2-x1=xb and y2-y1=yb.
Angle(vector.a,vector.b)=pi()/2*((1+sign(xa))(1-sign(ya^2))-(1+sign(xb))(1-sign(yb^2)))
+pi()/4*((2+sign(xa))*sign(ya)-(2+sign(xb))*sign(yb))
+sign(xa*ya)*atan((abs(xa)-abs(ya))/(abs(xa)+abs(ya)))
-sign(xb*yb)*atan((abs(xb)-abs(yb))/(abs(xb)+abs(yb)))
The formula gives angles from 0 to 2pi,for any value of xa,ya,xb and yb.
For xa=ya=0 and or xb=yb=0 the result is undefined.
Upvotes: 0
Reputation: 38042
Although StefanM's solution is a pretty common solution to this, it is actually computationally expensive, but most importantly, incorrect when the vectors are tiny and/or the angle is near 0 or π -- it can actually result in angles that are slightly negative, or slightly exceed π.
Thus, it gives a false sense of robustness. I'd instead suggest
theta = acos(min(1,max(-1, a(:).' * b(:) / norm(a) / norm(b) )));
More robust, more correct, over 10× faster when run in a loop, and understandable by laymen without documentation, because it still agrees mostly with the "classical" formula.
Upvotes: 6
Reputation: 194
I would suggest using a property of the dot product of two vectors. For clarity, I explained the details about the Math as well. Just skip it if you already know it. The following equation explains that property.
u · v = |u||v| cos θ
Source: http://chortle.ccsu.edu/VectorLessons/vch07/vch07_8.html
The left-hand side is the dot product. In the 2D case, u = [u1; u2] and v = [v1; v2]. The dot product is then multiplying the elements of each dimension and then summing. In this case thus u · v = u1*v1 + u2*v2.
On the right-hand side, the norms of both vectors are multiplied. A (Euclidean) norm of a 2D vector is described as (x1^2 + x2^2)^(1/2) for a vector x.
Now we discuss the Matlab code. We need a function which outputs theta with inputs of the two vectors.
function theta = calcAngleBetweenVectors(u, v)
dotUV = dot(u, v);
normU = norm(u);
normV = norm(v);
theta = acos(dotUV/(normU * normV));
To improve your function you should check for valid inputs. In this case these must be 2D vectors, although the function works for 2D as well.
Edit: Thank you Ander Biguri for pointing out the error in the dot product. I don't know what I was thinking
Upvotes: 2
Reputation: 3071
Let's call the points like this: (x1,y1)- person 1, (x2,y2)- future person 1, (x3,y3)- person2.
First_vec_angle=atan((y2-y1)/(x2-x1));
Second_vec_angle=atan((y3-y1)/(x3-x1));
Angle=Second_vec_angle-First_vec_angle;
Upvotes: 0
Reputation: 781
The Matlab Central gives following answer to your problem:
theta = atan2(norm(cross(a,b)),dot(a,b));
Where a
and b
are the vectors obtained by subtracting the positions.
Upvotes: 1