Measure angles between two vectors solely counter - clockwise
16 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Harvey Rael
el 17 de Jul. de 2018
Editada: Roberto Enrique
el 12 de En. de 2024
Hi,
I have two vectors and I want to measure the angle between them. The first one lies solely along the positive x-axis, and the second one varies in a circle. When the angle between the two gets greater than 180 degrees, MATLAB starts to measure the angle clockwise, but I would like it to continue to measure the angle counter clockwise. (e.g, after 180, measure 190, 200 etc.. instead of 170, 160 etc..). Any workarounds? Stuff like atan2 doesn't work. Thanks in advance!
2 comentarios
Jan
el 17 de Jul. de 2018
Matlab does not measure anything. But you can write some Matlab commands to calculate the angle. Of course atan2 does exactly, what is mathematically defined. But if you want to consider the sign in addition - consider the sign in addition.
Do you mean the 2D case, or are the vectors in 3D? In the latter case, "clockwise" or "counterclockwise" is not well defined, because it depends on the direction of view. Then please define this explicitly, because it is neither obvious nor uniquely defined in a mathematical sense.
The best idea is to post two example inputs and outputs together with the current code you use.
Adam Danz
el 17 de Jul. de 2018
Yeah, some examples will be helpful. A solution might be to use a conditional that detects cw or ccw outputs based on the sign of the angle and corrects for the undesired direction (assuming 2D).
if theta < 0
theta = 180 + (theta + 180);
end
or
if theta > 0
theta = -180 - (180-theta);
end
Respuesta aceptada
David Goodmanson
el 17 de Jul. de 2018
Editada: David Goodmanson
el 17 de Jul. de 2018
Hi Harvey,
It looks like you want the angle in degrees. For two dimensions, where the second vector has components x,y:
theta = mod(atan2d(y,x)+360,360)
4 comentarios
David Goodmanson
el 17 de Jul. de 2018
Going around clockwise from just below the negative x axis, the range of atan2d is continuous from -180 to 180. You want to add 360 to the result in Quadrants III and IV and leave Quadrants I and II alone.
Quadrants III, IV Quadrants I, II
atan2d -180 -> 0 0 -> 180
add 360 180 -> 360 ok 360 -> 540 no
mod(...,360) 180 -> 360 still ok 0 -> 180 ok
since mod subtracts (multiples of) 360 from anything larger than 360.
Más respuestas (2)
theodore panagos
el 10 de En. de 2019
The formula gives the angle from positive x-axis to 360 degrees counter clockwise:
f(x,y)=180-90*(1+sign(x))* (1-sign(y^2))-45*(2+sign(x)) *sign(y)
-(180/pi())*sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
x=x2-x1 and y=y2-y1 .
0 comentarios
Jan
el 17 de Jul. de 2018
Editada: Jan
el 17 de Jul. de 2018
In the 3D case:
function A = AngleIn3D(V1, V2, View)
% Input: V1, V2, View: [N x 3] vectors, each one can be [1 x 3] also.
% The angle between the vectors V1 and V2 is calculated
% The View defines the view direction to define the sign of the angle
%
% Method: atan2(norm(N1 x N2), DOT(N1, N2))
% W. Kahan suggested in "Mindeless.pdf":
% 2 * atan(norm(x*norm(y) - norm(x)*y) / norm(x * norm(y) + norm(x) * y))
N1 = V1 ./ sqrt(sum(V2 .* V2, 2)); % >= R2016b: arithmetic expanding!
N2 = V2 ./ sqrt(sum(V2 .* V2, 2)); % >= R2016b: arithmetic expanding!
% Calculate dot and cross product of vectors:
N1dotN2 = N1(:, 1) .* N2(:, 1) + N1(:, 2) .* N2(:, 2) + N1(:, 3) .* N2(:, 3);
N1xN2 = [(N1(:, 2) .* N2(:, 3) - N1(:, 3) .* N2(:, 2)), ...
(N1(:, 3) .* N2(:, 1) - N1(:, 1) .* N2(:, 3)), ...
(N1(:, 1) .* N2(:, 2) - N1(:, 2) .* N2(:, 1))];
% Angle between N1xN2 and view vector:
LXo = N1xN2(:, 1) .* View(:, 1) + N1xN2(:, 2) .* View(:, 2) + ...
N1xN2(:, 3) .* View(:, 3);
signLXo = sign(LXo);
% Care about anti-parallel N1 and N2:
antiN1N2 = (N1dotN2 < -0.999999999999993); % -1 + 3 * EPS
if any(antiN1N2)
antiN1N2 = and(antiN1N2, isfinite(N1dotN2)); % Catch N1dotN2=-Inf
signLXo(antiN1N2) = 1.0;
end
normN1xN2 = N1xN2 ./ sqrt(sum(N1xN2 .* N1xN2), 2);
Angle = signLXo .* atan2(normN1xN2, N1dotN2);
end
Now for the 2D case, set the 3rd component to 0 and use [0,0,1] as View direction. If you want the 2D case only, the above can be simplified massively.
function A = AngleIn2D(V1, V2)
% Input: V1, V2: [N x 3] vectors, each one can be [1 x 3] also.
% The angle between the vectors V1 and V2 is calculated
%
% Method: atan2(norm(N1 x N2), DOT(N1, N2))
% W. Kahan suggested in "Mindeless.pdf":
% 2 * atan(norm(x*norm(y) - norm(x)*y) / norm(x * norm(y) + norm(x) * y))
N1 = V1 ./ sqrt(sum(V2 .* V2, 2)); % >= R2016b: arithmetic expanding!
N2 = V2 ./ sqrt(sum(V2 .* V2, 2)); % >= R2016b: arithmetic expanding!
% Calculate dot and cross product of vectors:
N1dotN2 = N1(:, 1) .* N2(:, 1) + N1(:, 2) .* N2(:, 2);
N1xN2 = (N1(:, 1) .* N2(:, 2) - N1(:, 2) .* N2(:, 1));
% Angle between N1xN2 and view vector:
signLXo = sign(N1xN2);
% Care about anti-parallel N1 and N2:
antiN1N2 = (N1dotN2 < -0.999999999999993); % -1 + 3 * EPS
if any(antiN1N2)
antiN1N2 = and(antiN1N2, isfinite(N1dotN2)); % Catch N1dotN2=-Inf
signLXo(antiN1N2) = 1.0;
end
normN1xN2 = abs(N1xN2);
Angle = signLXo .* atan2(normN1xN2, N1dotN2);
end
!UNTESTED CODE!
2 comentarios
Roberto Enrique
el 12 de En. de 2024
Editada: Roberto Enrique
el 12 de En. de 2024
Hi! Jan, thank you for the code.
For 3D case i define V1=[0 0 0;1 1 1], V2=[1 1 1;2 3 4] and run the code as follows and the given errors
>> A = AngleIn3D(V1, V2, 1)
Index in position 2 exceeds array bounds. Index must not exceed 1.
Error in AngleIn3D (line 18)
LXo = N1xN2(:, 1) .* View(:, 1) + N1xN2(:, 2) .* View(:, 2) + N1xN2(:, 3) .* View(:, 3);
>> A = AngleIn3D(V1, V2, [1 0 0])
Error using sqrt
Too many input arguments.
Error in AngleIn3D (line 27)
normN1xN2 = N1xN2 ./ sqrt(sum(N1xN2 .* N1xN2), 2);
>> A = AngleIn3D(V1, V2, [0 0 0])
Error using sqrt
Too many input arguments.
Error in AngleIn3D (line 27)
normN1xN2 = N1xN2 ./ sqrt(sum(N1xN2 .* N1xN2), 2);
>> A = AngleIn3D(V1, V2, [1 1 1])
Error using sqrt
Too many input arguments.
Error in AngleIn3D (line 27)
normN1xN2 = N1xN2 ./ sqrt(sum(N1xN2 .* N1xN2), 2);
Could you help to solve this?
Thank you, sorry for my broken english
Ver también
Categorías
Más información sobre Matrix Indexing en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!