필터 지우기
필터 지우기

Finding angle of rotations from a given unit vector to rotate a given vector using those angle to align with the previous unit vector

조회 수: 24 (최근 30일)
I have a unit vector , let's say, b=[0.1844 -0.7417 0.6449] and I want to find the angle of rotations so that I can align a given vector a=[0 0 1] onto that unit vector,b. The way I started this problem is by finding the angle of rotations from the vector and then plugging them back inti the rotation matrix to allign a onto b in the same direction. But I'm stuck at this point. It's not giving me the angles correctly. I've attached my code below.
a=[0,0,1];
[R,theta_x,theta_y,Ry,Rx]=rot_xy(a(1,1),a(1,2),a(1,3));
test=R*a';
function [w,w_k,w_l,w_jk,w_kl ] = rot_xy( x,y,z)
% theta_x=-atand(y/sqrt(x^2+z^2));
% theta_y=pi-atand(x/z);
w_k=-atan(y/sqrt(x^2+z^2));
w_l=pi-atan(x/z);
%rot about y: tilt rotation
w_jk = [ cos(w_k) 0 sin(w_k) ;
0 1 0 ;
-sin(w_k) 0 cos(w_k) ];
%rot about x: twist rotation
w_kl = [ 1 0 0 ;
0 cos(w_l) -sin(w_l) ;
0 sin(w_l) cos(w_l) ];
w = w_jk * w_kl;
end
figure
plot3([0,a(1,1)],[0,a(1,2)],[0,a(1,3)],'r')
grid on
ax=gca;
ax.XColor='green';
ax.YColor='magenta';
grid on
axis([-.5 .5 -2.5 1 -1.5 1.5])
hold on
plot3([0,1.5*(b(1,1))],[0,1.5*(b(1,2))],[0,1.5*(b(1,3))],'k')
hold on
c=test';
hold on
plot3([0,c(1,1)],[0,c(1,2)],[0,c(1,3)],':r')
  댓글 수: 1
Matt J
Matt J 2019년 11월 12일
Generally speaking, representing the alignment as a rotation about x followed by y will either be impossible, or have two solutions. For example, it is easy to see that there is no solution for
a=[1 0 0 ].';
b=[0 1 0].';
Direct substitution into the equation b = w_jk * w_kl *a leads to
[0 1 0] = [cos(w_k) 0 -sin(w_k)]
which clearly has no solution.
Conversely, the following data has two solutions and two correspondingly different rotation matrices. You can reach b from a with either a rotation about x of t degrees followed by a 78 degree rotation about y. Or, you can do a rotation about x of -t degrees followed by a rotation about y of 102 degrees.
a =[
-0.874881810907645
0.484336470795830
0.000000000000000]
b =[
0
0.447213595499958
0.894427190999916]
t = 22.578683389390513;

댓글을 달려면 로그인하십시오.

채택된 답변

Matt J
Matt J 2019년 11월 12일
편집: Matt J 2019년 11월 12일
The following might be what you're looking for. It uses my AxelRot utility from the File Exchange
Or, if you only want theta, you could modify the code to return only that, which then wouldn't require AxelRot.
function [M,theta, Nrm]=vecrot(vstart,vend)
%Find rotation carrying one vector toward another about their common perpendicular
%axis.
%
%IN:
%
% vstart: Initial vector
% vend: Final vector
%
%OUT:
%
% M: homogeneous 4x4 rotation matrix carrying vstart to vend in a
% rotation about the axis Nrm=cross(vstart,vend)
% theta: the rotation angle in degrees
% Nrm: the rotation axis
vstart=vstart(:)/norm(vstart);
vend=vend(:)/norm(vend);
Nrm=cross(vstart,vend);
b=vend.'*vstart;
theta = atan2d(sqrt(1-b^2),b);
M=AxelRot(theta,Nrm,[]);
  댓글 수: 12
Matt J
Matt J 2019년 11월 16일
편집: Matt J 2019년 11월 16일
How would you define the result in those cases? There are infinite choices, but this one may serve:
if all(a==b)
R=eye(3);
elseif all(a==-b)
N=null(a(:).');
c=N(:,1);
M=vec_rot(a,c);
R=M(1:3,1:3)^2;
else
[M,theta, Nrm]=vec_rot(a,b);
R=M(1:3,1:3);
end

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by