// Check whether projection directions are unique ================================= bool directions_are_unique(double rot, double tilt, double rot2, double tilt2, double rot_limit, double tilt_limit, SymList &SL, bool include_mirrors, Matrix2D<double> &Laux, Matrix2D<double> &Raux) { bool are_unique = true; double rot2p, tilt2p, psi2p, psi2 = 0.; double diff_rot, diff_tilt; int isymmax=SL.symsNo(); for (int isym = 0; isym <= isymmax; isym++) { if (isym == 0) { rot2p = rot2; tilt2p = tilt2; psi2p = psi2; } else { SL.getMatrices(isym - 1, Laux, Raux,false); Euler_apply_transf(Laux, Raux, rot2, tilt2, psi2, rot2p, tilt2p, psi2p); } double aux=rot - rot2p; diff_rot = fabs(realWRAP(aux, -180, 180)); aux=tilt - tilt2p; diff_tilt = fabs(realWRAP(aux, -180, 180)); if ((rot_limit - diff_rot) > 1e-3 && (tilt_limit - diff_tilt) > 1e-3) are_unique = false; Euler_another_set(rot2p, tilt2p, psi2p, rot2p, tilt2p, psi2p); aux=rot - rot2p; diff_rot = fabs(realWRAP(aux, -180, 180)); aux=tilt - tilt2p; diff_tilt = fabs(realWRAP(aux, -180, 180)); if ((rot_limit - diff_rot) > 1e-3 && (tilt_limit - diff_tilt) > 1e-3) are_unique = false; if (!include_mirrors) { Euler_up_down(rot2p, tilt2p, psi2p, rot2p, tilt2p, psi2p); aux=rot - rot2p; diff_rot = fabs(realWRAP(aux, -180, 180)); aux=tilt - tilt2p; diff_tilt = fabs(realWRAP(aux, -180, 180)); if ((rot_limit - diff_rot) > 1e-3 && (tilt_limit - diff_tilt) > 1e-3) are_unique = false; Euler_another_set(rot2p, tilt2p, psi2p, rot2p, tilt2p, psi2p); aux=rot - rot2p; diff_rot = fabs(realWRAP(aux, -180, 180)); aux=tilt - tilt2p; diff_tilt = fabs(realWRAP(aux, -180, 180)); if ((rot_limit - diff_rot) > 1e-3 && (tilt_limit - diff_tilt) > 1e-3) are_unique = false; } } return are_unique; }
void run() { int iline = 0; FOR_ALL_OBJECTS_IN_METADATA_TABLE(MDu) { // Read input data DOUBLE rot1, tilt1, psi1; DOUBLE rot2, tilt2, psi2; DOUBLE rot2p, tilt2p, psi2p; DOUBLE best_tilt, best_alpha, best_beta; DOUBLE distp; MDu.getValue(EMDL_ORIENT_ROT, rot1); MDt.getValue(EMDL_ORIENT_ROT, rot2, iline); MDu.getValue(EMDL_ORIENT_TILT, tilt1); MDt.getValue(EMDL_ORIENT_TILT, tilt2, iline); MDu.getValue(EMDL_ORIENT_PSI, psi1); MDt.getValue(EMDL_ORIENT_PSI, psi2, iline); iline++; // Bring both angles to a normalized set rot1 = realWRAP(rot1, -180, 180); tilt1 = realWRAP(tilt1, -180, 180); psi1 = realWRAP(psi1, -180, 180); rot2 = realWRAP(rot2, -180, 180); tilt2 = realWRAP(tilt2, -180, 180); psi2 = realWRAP(psi2, -180, 180); // Apply rotations to find the minimum distance angles rot2p = rot2; tilt2p = tilt2; psi2p = psi2; distp = check_symmetries(rot1, tilt1, psi1, rot2p, tilt2p, psi2p); // Calculate distance to user-defined point DOUBLE xp, yp, x, y; Matrix1D<DOUBLE> aux2(4); xp = dist_from_tilt * COSD(dist_from_alpha); yp = dist_from_tilt * SIND(dist_from_alpha); x = tilt2p * COSD(rot2p); y = tilt2p * SIND(rot2p); aux2(3) = sqrt((xp-x)*(xp-x) + (yp-y)*(yp-y)); aux2(0) = tilt2p; aux2(1) = rot2p; aux2(2) = psi2p; add_to_postscript(tilt2p, rot2p, psi2p); } // Close the EPS file to write it to disk fh_eps << "showpage\n"; fh_eps.close(); }
double distance_directions(double rot1, double tilt1, double rot2, double tilt2, bool include_mirrors) { double rot2p, tilt2p, psi2p, dist; double diff_rot, diff_tilt; double aux=rot1 - rot2; diff_rot = fabs(realWRAP(aux, -180, 180)); aux=tilt1 - tilt2; diff_tilt = fabs(realWRAP(aux, -180, 180)); dist = sqrt((diff_rot * diff_rot) + (diff_tilt * diff_tilt)); Euler_another_set(rot2, tilt2, 0., rot2p, tilt2p, psi2p); aux=rot1 - rot2p; diff_rot = fabs(realWRAP(aux, -180, 180)); aux=tilt1 - tilt2p; diff_tilt = fabs(realWRAP(aux, -180, 180)); dist = fmin(dist, sqrt((diff_rot * diff_rot) + (diff_tilt * diff_tilt))); if (include_mirrors) { Euler_up_down(rot2, tilt2, 0., rot2p, tilt2p, psi2p); aux=rot1 - rot2p; diff_rot = fabs(realWRAP(aux, -180, 180)); aux=tilt1 - tilt2p; diff_tilt = fabs(realWRAP(aux, -180, 180)); dist = fmin(dist, sqrt((diff_rot * diff_rot) + (diff_tilt * diff_tilt))); Euler_another_set(rot2p, tilt2p, 0., rot2p, tilt2p, psi2p); aux=rot1 - rot2p; diff_rot = fabs(realWRAP(aux, -180, 180)); aux=tilt1 - tilt2p; diff_tilt = fabs(realWRAP(aux, -180, 180)); dist = fmin(dist, sqrt((diff_rot * diff_rot) + (diff_tilt * diff_tilt))); } return dist; }
DOUBLE check_tilt_pairs(DOUBLE rot1, DOUBLE tilt1, DOUBLE psi1, DOUBLE &alpha, DOUBLE &tilt_angle, DOUBLE &beta) { // Transformation matrices Matrix1D<DOUBLE> axis(3); Matrix2D<DOUBLE> E1, E2; axis.resize(3); DOUBLE aux, sine_tilt_angle; DOUBLE rot2 = alpha, tilt2 = tilt_angle, psi2 = beta; // Calculate the transformation from one setting to the second one. Euler_angles2matrix(psi1, tilt1, rot1, E1); Euler_angles2matrix(psi2, tilt2, rot2, E2); E2 = E2 * E1.inv(); // Get the tilt angle (and its sine) aux = ( E2(0,0) + E2(1,1) + E2(2,2) - 1. ) / 2.; if (ABS(aux) - 1. > XMIPP_EQUAL_ACCURACY) REPORT_ERROR("BUG: aux>1"); tilt_angle = ACOSD(aux); sine_tilt_angle = 2. * SIND(tilt_angle); // Get the tilt axis direction in angles alpha and beta if (sine_tilt_angle > XMIPP_EQUAL_ACCURACY) { axis(0) = ( E2(2,1) - E2(1,2) ) / sine_tilt_angle; axis(1) = ( E2(0,2) - E2(2,0) ) / sine_tilt_angle; axis(2) = ( E2(1,0) - E2(0,1) ) / sine_tilt_angle; } else { axis(0) = axis(1) = 0.; axis(2) = 1.; } // Apply E1.inv() to the axis to get everyone in the same coordinate system again axis = E1.inv() * axis; // Convert to alpha and beta angle Euler_direction2angles(axis, alpha, beta); // Enforce positive beta: choose the other Euler angle combination to express the same direction if (beta < 0.) { beta = -beta; alpha+= 180.; } // Let alpha go from 0 to 360 degrees alpha = realWRAP(alpha, 0., 360.); // Return the value that needs to be optimized DOUBLE minimizer=0.; if (exp_beta < 999.) minimizer = ABS(beta - exp_beta); if (exp_tilt < 999.) minimizer += ABS(tilt_angle - exp_tilt); return minimizer; }