From 0fed9bf29c2a3d15913f625e4ca45a50fb3bea26 Mon Sep 17 00:00:00 2001 From: Nicola Vigano <nicola.vigano@esrf.fr> Date: Wed, 6 May 2015 17:17:13 +0200 Subject: [PATCH] Euler/Rodrigues spaces: added and improved a few functions Signed-off-by: Nicola Vigano <nicola.vigano@esrf.fr> --- zUtil_Maths/gtMathsEuler2OriMat.m | 59 +++++++++++++++++------- zUtil_Maths/gtMathsEuler2RodInFundZone.m | 20 ++++++++ zUtil_Maths/gtMathsOriMat2Euler.m | 2 +- zUtil_Maths/gtMathsRod2Euler.m | 2 +- zUtil_Maths/gtMathsRod2RodInFundZone.m | 20 ++++++++ 5 files changed, 84 insertions(+), 19 deletions(-) create mode 100755 zUtil_Maths/gtMathsEuler2RodInFundZone.m create mode 100755 zUtil_Maths/gtMathsRod2RodInFundZone.m diff --git a/zUtil_Maths/gtMathsEuler2OriMat.m b/zUtil_Maths/gtMathsEuler2OriMat.m index 9ae36a20..7fa0eeff 100644 --- a/zUtil_Maths/gtMathsEuler2OriMat.m +++ b/zUtil_Maths/gtMathsEuler2OriMat.m @@ -1,4 +1,4 @@ -function g = gtMathsEuler2OriMat(euler) +function g = gtMathsEuler2OriMat(euler, convention) % GTMATHSEULER2ROTMAT Convert orientation matrices to Euler angles (degrees). % These follow Bunge convention (ZXZ) [phi1; phi; phi2]. % @@ -23,26 +23,51 @@ if size(euler, 1) ~= 3 'Input array euler should be sized 3xN!'); end +if (~exist('convention', 'var')) + convention = 'ZXZ'; +end + % Get number of Euler triplets N = size(euler, 1); % Reshape angles components euler = reshape(euler, 3, 1, []); -phi1 = euler(1, :, :); -phi = euler(2, :, :); -phi2 = euler(3, :, :); - -% Compute intermediate values -c1 = cosd(phi1); -cg = cosd(phi); -c2 = cosd(phi2); -s1 = sind(phi1); -sg = sind(phi); -s2 = sind(phi2); - -% Compute g matrices components -g = [ c1.*c2 - s1.*cg.*s2 , s1.*c2 + c1.*cg.*s2 , sg.*s2 ; ... - -c1.*s2 - s1.*cg.*c2 , c1.*cg.*c2 - s1.*s2 , sg.*c2 ; ... - s1.*sg , -c1.*sg , cg ]; + +switch (convention) + case 'ZXZ' + phi1 = euler(1, :, :); + phi = euler(2, :, :); + phi2 = euler(3, :, :); + + % Compute intermediate values + c1 = cosd(phi1); + cg = cosd(phi); + c2 = cosd(phi2); + s1 = sind(phi1); + sg = sind(phi); + s2 = sind(phi2); + + % Compute g matrices components + g = [ c1.*c2 - s1.*cg.*s2 , s1.*c2 + c1.*cg.*s2 , sg.*s2 ; ... + -c1.*s2 - s1.*cg.*c2 , c1.*cg.*c2 - s1.*s2 , sg.*c2 ; ... + s1.*sg , -c1.*sg , cg ]; + case 'XYZ' + phi = euler(1, :, :); + theta = euler(2, :, :); + psi = euler(3, :, :); + + % Compute intermediate values + c_phi = cosd(phi); + c_th = cosd(theta); + c_psi = cosd(psi); + s_phi = sind(phi); + s_th = sind(theta); + s_psi = sind(psi); + + % Compute g matrices components + g = [ c_th .* c_psi, c_th.*s_psi, -s_th; ... + s_phi .* s_th .* c_psi - c_phi .* s_psi, s_phi .* s_th .* s_psi + c_phi .* c_psi, c_th .* s_phi; ... + c_phi .* s_th .* c_psi + s_phi .* s_psi, c_phi .* s_th .* s_psi - s_phi .* c_psi, c_th .* c_phi ]; +end end % end of function diff --git a/zUtil_Maths/gtMathsEuler2RodInFundZone.m b/zUtil_Maths/gtMathsEuler2RodInFundZone.m new file mode 100755 index 00000000..95f0c576 --- /dev/null +++ b/zUtil_Maths/gtMathsEuler2RodInFundZone.m @@ -0,0 +1,20 @@ +function r_vec = gtMathsEuler2RodInFundZone(e_vec, symm) + g = gtMathsEuler2OriMat(e_vec); + + num_symm_ops = numel(symm); + + r_vecs = zeros(2 * num_symm_ops, 3); + + for ii = 1:num_symm_ops + r_vecs((ii - 1) * 2 + 1, :) = gtMathsOriMat2Rod(symm(ii).g3 * g); + r_vecs((ii - 1) * 2 + 2, :) = gtMathsOriMat2Rod(symm(ii).g3' * g); + end + + dists = 2 * atand(sqrt(sum(r_vecs .^ 2, 2))); + + [~, ii] = min(dists); + +% r_vecs + + r_vec = r_vecs(ii, :); +end diff --git a/zUtil_Maths/gtMathsOriMat2Euler.m b/zUtil_Maths/gtMathsOriMat2Euler.m index afe02e39..7d89d979 100644 --- a/zUtil_Maths/gtMathsOriMat2Euler.m +++ b/zUtil_Maths/gtMathsOriMat2Euler.m @@ -43,7 +43,7 @@ phi2 = double(singular).*phi1; phi2 = phi2 + double(regular ).*atan2(g(1, 3, :), g(2, 3, :)); % Gather all Euler angles in an array -euler = rad2deg([ phi1 ; phi ; phi2 ]); +euler = [ phi1 ; phi ; phi2 ] * 180 / pi; % Shift to positive angles range euler = mod(euler, 360.); diff --git a/zUtil_Maths/gtMathsRod2Euler.m b/zUtil_Maths/gtMathsRod2Euler.m index a4535841..bfa7bf97 100644 --- a/zUtil_Maths/gtMathsRod2Euler.m +++ b/zUtil_Maths/gtMathsRod2Euler.m @@ -41,7 +41,7 @@ phi = 2*atan2(sqrt(r(1, :).^2 + r(2, :).^2), sqrt(1. + r(3, :).^2)); phi2 = b - a; % Switch to degrees -euler = rad2deg([phi1 ; phi ; phi2]); +euler = [phi1 ; phi ; phi2] * 180 / pi; % Shift to positive angles range euler = mod(euler, 360.); diff --git a/zUtil_Maths/gtMathsRod2RodInFundZone.m b/zUtil_Maths/gtMathsRod2RodInFundZone.m new file mode 100755 index 00000000..f8e46305 --- /dev/null +++ b/zUtil_Maths/gtMathsRod2RodInFundZone.m @@ -0,0 +1,20 @@ +function r_vec = gtMathsRod2RodInFundZone(r_vec, symm) + g = gtMathsRod2OriMat(r_vec); + + num_symm_ops = numel(symm); + + r_vecs = zeros(2 * num_symm_ops, 3); + + for ii = 1:num_symm_ops + r_vecs((ii - 1) * 2 + 1, :) = gtMathsOriMat2Rod(symm(ii).g3 * g); + r_vecs((ii - 1) * 2 + 2, :) = gtMathsOriMat2Rod(symm(ii).g3' * g); + end + + dists = 2 * atand(sqrt(sum(r_vecs .^ 2, 2))); + + [~, ii] = min(dists); + +% r_vecs + + r_vec = r_vecs(ii, :); +end -- GitLab