1
votes

I have two coordinate vectors:

coor1 = [4 2];
coor2 = [4.3589 1];

and I want to find the angle of the rotation, where mathematically it is given by the equation:

enter image description here

where the numerator is the cross product between the two coordinate pairs and the denominator is the dot product.

The problem is that in MATLAB, a cross product isn't possible with 2-element vectors. Running the following code:

ang = atan2(norm(cross(coor1,coor2)),dot(coor1,coor2));

produces this error:

Error using cross
A and B must be of length 3 in the dimension in which the cross product is taken. 

Is there any way to make cross work? Working this out by hand, the angle of the rotation of both coordinate should be 13.6441.

5
What about rad2deg(atan2(coor2(2)*coor1(1)-coor2(1)*coor1(2), dot(coor1,coor2)))?avermaet
@avermaet rad2deg(atan2(...)) is unnecessary, one can simply use atan2d instead.Dev-iL
Any reason why you're not accepting an answer?Dev-iL
@Dev-iL my bad, totally forgotten about that. Wish i could accept all answers as they're all valid.Maxxx

5 Answers

4
votes

Convert vectors to complex numbers and use angle:

x=coor1 * [1; 1i];
y=coor2 * [1; 1i];
ang = angle(x*y')

Other vectorized solution that can convert multiple vectors:

atan2(coor1 * (coor2(:,[2,1]).*[1 -1]).',coor1 * coor2.')

*Thanks to @Dev-iL I changed i to 1i.

3
votes

You can append a zero to the vectors to make them 3D, and then get the 3rd element from the normal vector:

n = cross([coor1 0], [coor2 0]);
theta = atan2(n(3),dot(coor1,coor2));
3
votes

With:

x = [4 2];
y = [4.3589 1];

You can use the determinant

ang = atan2d(det([x;y]),dot(x,y))

Noticed that since the unit circle is defined counterclockwise, with this example the angle will be negative. Also using the determinant is mathematically/theoretically wrong, but with a matrix 2x2the result is the same.

2
votes

Why not use the inverse cosine (arccos) instead?

coor1 = [4 2];
coor2 = [4.3589 1];

% normalize the vectors:
d1 = coor1 ./ norm(coor1);
d2 = coor2 ./ norm(coor2);

ang = acosd(dot(d1,d2));
2
votes

I suggest you use an anonymous function to implement it directly like in my comment:

cross2 = @(coor1,coor2)(coor2(2)*coor1(1)-coor2(1)*coor1(2))

Now you can use it just like a normal function. I think this should be the ideal solution regarding the number of operations but also for reusability.

atan2d(cross2(coor1,coor2),dot(coor1,coor2)) % Thanks @Dev-iL