-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrot2qua.m
53 lines (42 loc) · 1.46 KB
/
rot2qua.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
function [ q ] = rot2qua( R, checko, tran )
% R is a 3-by-3-by-n matrix
% if tran==false, q returns a 4-by-n matrix
% if tran==true, q returns a n-by-4 matrix
% if checko==true (default), check if R is orthogonal with determinant one.
if ~exist('checko','var') || isempty(checko)
checko = true;
end
if ~exist('tran','var') || isempty(tran)
tran = false;
end
% check size and orthogonality
if size(R,1)~=3 || size(R,2)~=3
error('R must be of size 3-3-n');
end
orthogonalTolerance = 1e-10;
unitnessTolerance = 1e-10;
if checko
if ~isempty(find(abs(sqrt(sum(R(:,1,:).^2))-1)>unitnessTolerance,1)) ||...
~isempty(find(abs(sqrt(sum(R(:,2,:).^2))-1)>unitnessTolerance,1)) ||...
~isempty(find(abs(sqrt(sum(R(:,3,:).^2))-1)>unitnessTolerance,1)) ||...
~isempty(find(abs(sum(R(:,1,:).*R(:,2,:)))>orthogonalTolerance,1)) ||...
~isempty(find(abs(sum(R(:,1,:).*R(:,3,:)))>orthogonalTolerance,1)) ||...
~isempty(find(abs(sum(R(:,2,:).*R(:,3,:)))>orthogonalTolerance,1)) ||...
~isempty(find(detM3(R)<0,1))
error('R must be orthogonal matrices');
end
end
% calculate
v = logRot(R,'v',false);
q = expQua(v);
% format result
if tran
q = q';
end
end
function [ d ] = detM3( R )
d = R(1,1,:).*R(2,2,:).*R(3,3,:)+R(1,2,:).*R(2,3,:).*R(3,1,:)+...
R(1,3,:).*R(2,1,:).*R(3,2,:)-R(1,3,:).*R(2,2,:).*R(3,1,:)-...
R(1,2,:).*R(2,1,:).*R(3,3,:)-R(1,1,:).*R(2,3,:).*R(3,2,:);
d = reshape(d,1,[],1);
end