Xmipp  v3.23.11-Nereus
Classes
Collaboration diagram for Geometry:

Classes

struct  FitPoint
 
struct  fit_point2D
 
class  Bspline_model
 

Geometrical operations

void Uproject_to_plane (const Matrix1D< double > &point, const Matrix1D< double > &direction, double distance, Matrix1D< double > &result)
 
void Uproject_to_plane (const Matrix1D< double > &r, double rot, double tilt, double psi, Matrix1D< double > &result)
 
void Uproject_to_plane (const Matrix1D< double > &r, const Matrix2D< double > &euler, Matrix1D< double > &result)
 
double spherical_distance (const Matrix1D< double > &r1, const Matrix1D< double > &r2)
 
double point_line_distance_3D (const Matrix1D< double > &p, const Matrix1D< double > &a, const Matrix1D< double > &v)
 
double point_plane_distance_3D (const Matrix1D< double > &p, const Matrix1D< double > &a, const Matrix1D< double > &v)
 
void least_squares_plane_fit (FitPoint *IN_points, int Npoints, double &plane_A, double &plane_B, double &plane_C)
 
void least_squares_plane_fit_All_Points (const MultidimArray< double > &Image, double &plane_A, double &plane_B, double &plane_C)
 
void least_squares_line_fit (const std::vector< fit_point2D > &IN_points, double &line_A, double &line_B)
 
void Bspline_model_fitting (const std::vector< FitPoint > &IN_points, int SplineDegree, int l0, int lF, int m0, int mF, double h_x, double h_y, double x0, double y0, Bspline_model &result)
 
void rectangle_enclosing (const Matrix1D< double > &v0, const Matrix1D< double > &vF, const Matrix2D< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
 
void box_enclosing (const Matrix1D< double > &v0, const Matrix1D< double > &vF, const Matrix2D< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
 
bool point_inside_polygon (const std::vector< Matrix1D< double > > &polygon, const Matrix1D< double > &point)
 
void def_affinity (double u1x, double u1y, double u2x, double u2y, double u3x, double u3y, double t1x, double t1y, double t2x, double t2y, double t3x, double t3y, Matrix2D< double > &A, Matrix1D< double > &T, Matrix2D< double > &invW)
 
double triangle_area (double x1, double y1, double x2, double y2, double x3, double y3)
 
int line_plane_intersection (const Matrix1D< double > normal_plane, const Matrix1D< double > vector_line, Matrix1D< double > &intersection_point, const Matrix1D< double > point_line, double point_plane_at_x_y_zero=0.)
 

Euler operations

template<typename T >
void Euler_angles2matrix (T a, T b, T g, Matrix2D< T > &A, bool homogeneous=false)
 
void Euler_anglesZXZ2matrix (double a, double b, double g, Matrix2D< double > &A, bool homogeneous=false)
 
double Euler_distanceBetweenMatrices (const Matrix2D< double > &E1, const Matrix2D< double > &E2)
 
template<typename T >
Euler_distanceBetweenAngleSets (T rot1, T tilt1, T psi1, T rot2, T tilt2, T psi2, bool only_projdir)
 
template<typename T >
Euler_distanceBetweenAngleSets_fast (const Matrix2D< T > &E1, T rot2, T tilt2, T psi2, bool only_projdir, Matrix2D< T > &E2)
 
void Euler_Angles_after_compresion (const double rot, double tilt, double psi, double &new_rot, double &new_tilt, double &new_psi, Matrix2D< double > &D)
 
void Euler_direction (double alpha, double beta, double gamma, Matrix1D< double > &v)
 
void Euler_direction2angles (Matrix1D< double > &v, double &alpha, double &beta, double &gamma)
 
void Euler_matrix2angles (const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous=false)
 
void Euler_up_down (double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
 
void Euler_another_set (double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
 
void Euler_mirrorY (double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
 
void Euler_mirrorX (double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
 
void Euler_mirrorXY (double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
 
void Euler_apply_transf (const Matrix2D< double > &L, const Matrix2D< double > &R, double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
 
void Euler_rotate (const MultidimArray< double > &V, double rot, double tilt, double psi, MultidimArray< double > &result)
 
void Euler_rotate (const MultidimArrayGeneric &V, double rot, double tilt, double psi, MultidimArray< double > &result)
 
void computeCircleAroundE (const Matrix2D< double > &E, double angCircle, double angStep, std::vector< double > &outputEulerAngles)
 
#define EULER_CLIPPING(rot, tilt, psi)
 
#define EULER_CLIPPING_RAD(rot, tilt, psi)
 

Intersections

double intersection_unit_sphere (const Matrix1D< double > &u, const Matrix1D< double > &r)
 
double intersection_unit_cylinder (const Matrix1D< double > &u, const Matrix1D< double > &r)
 
double intersection_unit_cube (const Matrix1D< double > &u, const Matrix1D< double > &r)
 

Detailed Description

Macro Definition Documentation

◆ EULER_CLIPPING

#define EULER_CLIPPING (   rot,
  tilt,
  psi 
)
Value:
rot = realWRAP(rot, 0, 360); \
tilt = realWRAP(tilt, 0, 360); \
psi = realWRAP(psi, 0, 360);
double psi(const double x)
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304

Getting the Euler angles to a range (0-360). No direction equivalence is applied, ie, there is no correction of the direction of projection making use that a view from the top is the same as a view from the bottom but reversed ... Just a wrapping of the angles is done until the angles fall in the specified ranges. The angles given must be variables and they are modified with the new values.

Definition at line 471 of file geometry.h.

◆ EULER_CLIPPING_RAD

#define EULER_CLIPPING_RAD (   rot,
  tilt,
  psi 
)
Value:
rot = realWRAP(rot, 0, 2.0*PI); \
tilt = realWRAP(tilt, 0, 2.0*PI); \
psi = realWRAP(psi, 0, 2.0*PI);
double psi(const double x)
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304
#define PI
Definition: tools.h:43

Getting the Euler angles to a range (0-2*PI).

The same as before but the angles are expressed in radians.

Definition at line 480 of file geometry.h.

Function Documentation

◆ box_enclosing()

void box_enclosing ( const Matrix1D< double > &  v0,
const Matrix1D< double > &  vF,
const Matrix2D< double > &  V,
Matrix1D< double > &  corner1,
Matrix1D< double > &  corner2 
)

Box which encloses a deformed box

Given a box characterized by the top-left corner (most negative) and the right-bottom (most positive) corner, and given a matrix after which the box is deformed. Which is the minimum box which encloses the preceding one? This function is useful for stablishing for loops which will cover for sure the deformed box. All vectors are supposed to be 3x1 and the deformation matrix is 3x3. The corner (x0,y0,z0) goes to V*(x0,y0,z0)' and (xF,yF,zF) to V*(xf,yF,zF)'. After that you can make a loop from corner1 to corner2.

The v0 and vF vectors can be reused as outputs.

Definition at line 366 of file geometry.cpp.

369 {
371  Matrix1D<double> v(3);
372  corner1.resize(3);
373  corner2.resize(3);
374 
375  // Store values for reusing input as output vectors
376  double XX_v0 = XX(v0);
377  double YY_v0 = YY(v0);
378  double ZZ_v0 = ZZ(v0);
379  double XX_vF = XX(vF);
380  double YY_vF = YY(vF);
381  double ZZ_vF = ZZ(vF);
382 
383  VECTOR_R3(v, XX_v0, YY_v0, ZZ_v0);
384  M3x3_BY_V3x1(v, V, v);
385  XX(corner1) = XX(v);
386  XX(corner2) = XX(v);
387  YY(corner1) = YY(v);
388  YY(corner2) = YY(v);
389  ZZ(corner1) = ZZ(v);
390  ZZ(corner2) = ZZ(v);
391 
392 #define DEFORM_AND_CHOOSE_CORNERS3D \
393  M3x3_BY_V3x1(v,V,v); \
394  XX(corner1)=XMIPP_MIN(XX(corner1),XX(v)); \
395  XX(corner2)=XMIPP_MAX(XX(corner2),XX(v)); \
396  YY(corner1)=XMIPP_MIN(YY(corner1),YY(v)); \
397  YY(corner2)=XMIPP_MAX(YY(corner2),YY(v)); \
398  ZZ(corner1)=XMIPP_MIN(ZZ(corner1),ZZ(v)); \
399  ZZ(corner2)=XMIPP_MAX(ZZ(corner2),ZZ(v));
400 
401  VECTOR_R3(v, XX_vF, YY_v0, ZZ_v0);
403  VECTOR_R3(v, XX_v0, YY_vF, ZZ_v0);
405  VECTOR_R3(v, XX_vF, YY_vF, ZZ_v0);
407  VECTOR_R3(v, XX_v0, YY_v0, ZZ_vF);
409  VECTOR_R3(v, XX_vF, YY_v0, ZZ_vF);
411  VECTOR_R3(v, XX_v0, YY_vF, ZZ_vF);
413  VECTOR_R3(v, XX_vF, YY_vF, ZZ_vF);
415 }
#define DEFORM_AND_CHOOSE_CORNERS3D
#define XX(v)
Definition: matrix1d.h:85
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define M3x3_BY_V3x1(a, M, b)
Definition: matrix2d.h:170
#define YY(v)
Definition: matrix1d.h:93
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
#define ZZ(v)
Definition: matrix1d.h:101
#define SPEED_UP_temps012
Definition: xmipp_macros.h:403

◆ Bspline_model_fitting()

void Bspline_model_fitting ( const std::vector< FitPoint > &  IN_points,
int  SplineDegree,
int  l0,
int  lF,
int  m0,
int  mF,
double  h_x,
double  h_y,
double  x0,
double  y0,
Bspline_model result 
)

Least-squares fit of a B-spline 2D model

For fitting a set of values that are distributed between (x0,y0) and (xF,yF) with a cubic Bspline centered on each corner, the right call is

Bspline_model_fitting(list_of_points, 3, -1, 2, -1, 2, xF-x0, yF-y0, x0,
y0, model);

Once the model is returned you can evaluate it at any point simply by

model.evaluate(x,y);

Definition at line 243 of file geometry.cpp.

247 {
248  // Initialize model
249  result.l0 = l0;
250  result.lF = lF;
251  result.m0 = m0;
252  result.mF = mF;
253  result.x0 = x0;
254  result.y0 = y0;
255  result.SplineDegree = SplineDegree;
256  result.h_x = h_x;
257  result.h_y = h_y;
258  result.c_ml.initZeros(mF - m0 + 1, lF - l0 + 1);
259  STARTINGY(result.c_ml) = m0;
260  STARTINGX(result.c_ml) = l0;
261 
262  // Modify the list of points to include the weight
263  int Npoints = IN_points.size();
264  std::vector<FitPoint> AUX_points = IN_points;
265  for (int i = 0; i < Npoints; ++i)
266  {
267  double sqrt_w = sqrt(AUX_points[i].w);
268  AUX_points[i].x *= sqrt_w;
269  AUX_points[i].y *= sqrt_w;
270  AUX_points[i].z *= sqrt_w;
271  }
272 
273  // Now solve the normal linear regression problem
274  // Ax=B
275  // A=system matrix
276  // x=B-spline coefficients
277  // B=vector of measured values
278  int Ncoeff = YSIZE(result.c_ml) * XSIZE(result.c_ml);
279  Matrix2D<double> A(Npoints, Ncoeff);
280  Matrix1D<double> B(Npoints);
281  for (int i = 0; i < Npoints; ++i)
282  {
283  B(i) = AUX_points[i].z;
284  double xarg = (AUX_points[i].x - x0) / h_x;
285  double yarg = (AUX_points[i].y - y0) / h_y;
286  for (int m = m0; m <= mF; ++m)
287  for (int l = l0; l <= lF; ++l)
288  {
289  double coeff=0.;
290  switch (SplineDegree)
291  {
292  case 2:
293  coeff = Bspline02(xarg - l) * Bspline02(yarg - m);
294  break;
295  case 3:
296  coeff = Bspline03(xarg - l) * Bspline03(yarg - m);
297  break;
298  case 4:
299  coeff = Bspline04(xarg - l) * Bspline04(yarg - m);
300  break;
301  case 5:
302  coeff = Bspline05(xarg - l) * Bspline05(yarg - m);
303  break;
304  case 6:
305  coeff = Bspline06(xarg - l) * Bspline06(yarg - m);
306  break;
307  case 7:
308  coeff = Bspline07(xarg - l) * Bspline07(yarg - m);
309  break;
310  case 8:
311  coeff = Bspline08(xarg - l) * Bspline08(yarg - m);
312  break;
313  case 9:
314  coeff = Bspline09(xarg - l) * Bspline09(yarg - m);
315  break;
316  }
317  A(i, (m - m0)*XSIZE(result.c_ml) + l - l0) = coeff;
318  }
319  }
320 
321  Matrix1D<double> x = (A.transpose() * A).inv() * (A.transpose() * B);
322  for (int m = m0; m <= mF; ++m)
323  for (int l = l0; l <= lF; ++l)
324  result.c_ml(m, l) = x((m - m0) * XSIZE(result.c_ml) + l - l0);
325 }
#define YSIZE(v)
double Bspline05(double Argument)
double y0
y0
Definition: geometry.h:288
int lF
lF;
Definition: geometry.h:279
void sqrt(Image< double > &op)
doublereal * w
#define STARTINGX(v)
int l0
l0
Definition: geometry.h:277
doublereal * x
#define i
double x0
x0
Definition: geometry.h:286
double Bspline04(double Argument)
#define STARTINGY(v)
#define y0
#define x0
#define XSIZE(v)
int SplineDegree
Order of the Bspline.
Definition: geometry.h:291
double Bspline03(double Argument)
double Bspline07(double Argument)
double Bspline08(double Argument)
int m
double Bspline02(double Argument)
MultidimArray< double > c_ml
Definition: geometry.h:302
double Bspline09(double Argument)
int mF
mF;
Definition: geometry.h:283
void initZeros(const MultidimArray< T1 > &op)
double Bspline06(double Argument)
double h_y
Scale Y.
Definition: geometry.h:296
int m0
m0
Definition: geometry.h:281
double h_x
Scale X.
Definition: geometry.h:294

◆ computeCircleAroundE()

void computeCircleAroundE ( const Matrix2D< double > &  E,
double  angCircle,
double  angStep,
std::vector< double > &  outputEulerAngles 
)

Compute circle around Euler matrix

Given an input Euler matrix, this function returns a set of Euler angles such that they sample a circle around the original projection direction (a sample every angStep). The projection directions in the circle are separated by angCircle.

The output is in outputEulerAngles whose structure is (newrot1,newtilt1,newpsi1,newrot2,newtilt2,newpsi2,...)

Definition at line 1078 of file geometry.cpp.

1080 {
1081  outputEulerAngles.clear();
1082 
1083  // Get the projection direction and a perpendicular direction
1084  Matrix1D<double> projectionDirection, perpendicular;
1085  E.getRow(1,perpendicular);
1086  E.getRow(2,projectionDirection);
1087  Matrix2D<double> newEt;
1088  newEt = E.transpose();
1089  Matrix2D<double> rotStep, sampling;
1090  rotation3DMatrix(angCircle,perpendicular,rotStep,false);
1091  rotation3DMatrix(angStep,projectionDirection,sampling,false);
1092 
1093  // Now rotate
1094  newEt = rotStep*newEt;
1095  for (double i = 0; i < 360; i += angStep)
1096  {
1097  newEt=sampling*newEt;
1098 
1099  // Normalize
1100  for (int c=0; c<3; c++)
1101  {
1102  Matrix1D<double> aux;
1103  newEt.getCol(c,aux);
1104  aux/=aux.module();
1105  newEt.setCol(c,aux);
1106  }
1107  Matrix2D<double> newE=newEt.transpose();
1108 
1109  double newrot, newtilt, newpsi;
1110  Euler_matrix2angles(newE,newrot,newtilt,newpsi);
1111  outputEulerAngles.push_back(newrot);
1112  outputEulerAngles.push_back(newtilt);
1113  outputEulerAngles.push_back(newpsi);
1114  }
1115 }
double module() const
Definition: matrix1d.h:983
doublereal * c
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
#define i
void rotation3DMatrix(double ang, char axis, Matrix2D< double > &result, bool homogeneous)
#define sampling
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871

◆ def_affinity()

void def_affinity ( double  u1x,
double  u1y,
double  u2x,
double  u2y,
double  u3x,
double  u3y,
double  t1x,
double  t1y,
double  t2x,
double  t2y,
double  t3x,
double  t3y,
Matrix2D< double > &  A,
Matrix1D< double > &  T,
Matrix2D< double > &  invW 
)

Affine transformation

Definition at line 441 of file geometry.cpp.

443 {
444  double den = (u1x*u2y - u1y*u2x - u1x*u3y + u1y*u3x + u2x*u3y - u2y*u3x);
445 
446  //std::cout << "den" <<k << std::endl;
447 
448  invW.initZeros(6,6);
449  MAT_ELEM(invW,0,0) = MAT_ELEM(invW,2,3) = (u2y - u3y)/den;
450  MAT_ELEM(invW,0,1) = MAT_ELEM(invW,2,4) = -(u1y - u3y)/den;
451  MAT_ELEM(invW,0,2) = MAT_ELEM(invW,2,5) = (u1y - u2y)/den;
452 
453  MAT_ELEM(invW,1,0) = MAT_ELEM(invW,3,3) = -(u2x - u3x)/den;
454  MAT_ELEM(invW,1,1) = MAT_ELEM(invW,3,4) = (u1x - u3x)/den;
455  MAT_ELEM(invW,1,2) = MAT_ELEM(invW,3,5) = -(u1x - u2x)/den;
456 
457  MAT_ELEM(invW,4,0) = MAT_ELEM(invW,5,3) = (u2x*u3y - u2y*u3x)/den;
458  MAT_ELEM(invW,4,1) = MAT_ELEM(invW,5,4) = -(u1x*u3y - u1y*u3x)/den;
459  MAT_ELEM(invW,4,2) = MAT_ELEM(invW,5,5) = (u1x*u2y - u1y*u2x)/den;
460 
461 
462 
463  Matrix1D<double> t_vec;
464  t_vec.initZeros(6);
465  VEC_ELEM(t_vec,0) = t1x;
466  VEC_ELEM(t_vec,1) = t2x;
467  VEC_ELEM(t_vec,2) = t3x;
468  VEC_ELEM(t_vec,3) = t1y;
469  VEC_ELEM(t_vec,4) = t2y;
470  VEC_ELEM(t_vec,5) = t3y;
471 
472  double dettt = invW.det();
473  //std::cout << "determinant" << dettt << std::endl;
474 
475  //Matrix1D<double> sol = invW*t_vec;
476  //std::cout << "sol = " << sol << std::endl;
477 
478  if (fabs(dettt) < DBL_EPSILON )
479  {
480  //std::cout << "I'm in if" << std::endl;
481  A.initZeros(2,2);
482  T.initZeros(2);
483  VEC_ELEM(T,0) = DBL_MAX ;
484  VEC_ELEM(T,1) = DBL_MAX ;
485  }
486  else
487  {
488  //std::cout << "I'm in else" << std::endl;
489  Matrix1D<double> sol = invW*t_vec;
490  //std::cout << "sol = " << sol << std::endl;
491 
492  A.initZeros(2,2);
493  T.initZeros(2);
494  //std::cout << A << std::endl;
495  MAT_ELEM(A,0,0) = VEC_ELEM(sol,0);
496  MAT_ELEM(A,0,1) = VEC_ELEM(sol,1);
497  MAT_ELEM(A,1,0) = VEC_ELEM(sol,2);
498  MAT_ELEM(A,1,1) = VEC_ELEM(sol,3);
499  VEC_ELEM(T,0) = VEC_ELEM(sol,4);
500  VEC_ELEM(T,1) = VEC_ELEM(sol,5);
501 
502  //std::cout << "A ==" << sol << std::endl;
503  }
504 }
#define DBL_EPSILON
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
T det() const
Definition: matrix2d.cpp:38
void initZeros()
Definition: matrix1d.h:592
#define DBL_MAX
void initZeros()
Definition: matrix2d.h:626

◆ Euler_angles2matrix()

template<typename T >
void Euler_angles2matrix ( a,
b,
g,
Matrix2D< T > &  A,
bool  homogeneous = false 
)

Euler angles –> Euler matrix.

This function returns the transformation matrix associated to the 3 given Euler angles (in degrees).

As an implementation note you might like to know that this function calls always to Matrix2D::resize

See http://xmipp.cnb.csic.es/twiki/bin/view/Xmipp/EulerAngles for a description of the Euler angles.

Definition at line 624 of file geometry.cpp.

626 {
627  static_assert(std::is_floating_point<T>::value, "Only float and double are allowed as template parameters");
628 
629  if (homogeneous)
630  {
631  A.initZeros(4,4);
632  MAT_ELEM(A,3,3)=1;
633  }
634  else
635  if (MAT_XSIZE(A) != 3 || MAT_YSIZE(A) != 3)
636  A.resizeNoCopy(3, 3);
637 
638  T ca = std::cos(DEG2RAD(alpha));
639  T sa = std::sin(DEG2RAD(alpha));
640  T cb = std::cos(DEG2RAD(beta));
641  T sb = std::sin(DEG2RAD(beta));
642  T cg = std::cos(DEG2RAD(gamma));
643  T sg = std::sin(DEG2RAD(gamma));
644 
645  T cc = cb * ca;
646  T cs = cb * sa;
647  T sc = sb * ca;
648  T ss = sb * sa;
649 
650  MAT_ELEM(A, 0, 0) = cg * cc - sg * sa;
651  MAT_ELEM(A, 0, 1) = cg * cs + sg * ca;
652  MAT_ELEM(A, 0, 2) = -cg * sb;
653  MAT_ELEM(A, 1, 0) = -sg * cc - cg * sa;
654  MAT_ELEM(A, 1, 1) = -sg * cs + cg * ca;
655  MAT_ELEM(A, 1, 2) = sg * sb;
656  MAT_ELEM(A, 2, 0) = sc;
657  MAT_ELEM(A, 2, 1) = ss;
658  MAT_ELEM(A, 2, 2) = cb;
659 }
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
double beta(const double a, const double b)
double * gamma
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
struct _constraint * cs
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
void initZeros()
Definition: matrix2d.h:626

◆ Euler_Angles_after_compresion()

void Euler_Angles_after_compresion ( const double  rot,
double  tilt,
double  psi,
double &  new_rot,
double &  new_tilt,
double &  new_psi,
Matrix2D< double > &  D 
)

Angles after compresion

Let be two volumes f and g related by g(x,y,z) = f(D(x,y,z)) (where D is a lineal transformation) then the projection direction parallel to the vector w in f is going to be related with the projection direction parallel to the vector w_prime in g. Given the w Euler angles this routine provide the w_prime angles

Definition at line 955 of file geometry.cpp.

957 {
958  Matrix1D<double> w(3);
959  Matrix1D<double> new_w(3);
960  Matrix2D<double> D_1(3, 3);
961 
962  //if D has not inverse we are not in business
963  D_1 = D.inv();
964 
965  Euler_direction(rot, tilt, psi, w);
966  if (fabs(w(2)) > 0.999847695)/*cos one degree */
967  {
968  Euler_direction(rot, 10., psi, w);
969  new_w = (Matrix1D<double>)(D_1 * w) / ((D_1 * w).module());
970  Euler_direction2angles(new_w, new_rot, new_tilt, new_psi);
971 
972  Euler_direction(rot, tilt, psi, w);
973  new_w = (Matrix1D<double>)((D_1 * w) / ((D_1 * w).module()));
974  new_tilt = SGN(new_tilt) * fabs(ACOSD(new_w(2)));
975  new_psi = psi;
976 
977  // so, for small tilt the value of the rot is not realiable
978  // doubleo overcome this problem I first calculate the rot for
979  // any arbitrary large tilt angle and the right rotation
980  // and then I calculate the new tilt.
981  // Please notice that the new_rotation is not a funcion of
982  // the old tilt angle so I can use any arbitrary tilt angle
983  }
984  else
985  {
986  new_w = (Matrix1D<double>)(D_1 * w) / ((D_1 * w).module());
987  Euler_direction2angles(new_w, new_rot, new_tilt, new_psi);
988  new_psi = psi;
989  }
990 }
void Euler_direction(double alpha, double beta, double gamma, Matrix1D< double > &v)
Definition: geometry.cpp:721
void Euler_direction2angles(Matrix1D< double > &v0, double &alpha, double &beta, double &gamma)
Definition: geometry.cpp:746
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
doublereal * w
#define ACOSD(x)
Definition: xmipp_macros.h:338
double psi(const double x)
#define SGN(x)
Definition: xmipp_macros.h:155

◆ Euler_anglesZXZ2matrix()

void Euler_anglesZXZ2matrix ( double  a,
double  b,
double  g,
Matrix2D< double > &  A,
bool  homogeneous = false 
)

Euler angles –> Euler matrix.

This function returns the transformation matrix associated to the 3 given Euler angles (in degrees).

Definition at line 661 of file geometry.cpp.

662 {
663  Matrix2D<double> RZ1, RX2, RZ3;
664  rotation3DMatrix(a,'Z',RZ1,homogeneous);
665  rotation3DMatrix(b,'X',RX2,homogeneous);
666  rotation3DMatrix(g,'Z',RZ3,homogeneous);
667  A=RZ3*RX2*RZ1;
668 }
doublereal * g
void rotation3DMatrix(double ang, char axis, Matrix2D< double > &result, bool homogeneous)
doublereal * b
doublereal * a

◆ Euler_another_set()

void Euler_another_set ( double  rot,
double  tilt,
double  psi,
double &  newrot,
double &  newtilt,
double &  newpsi 
)

The same view but differently expressed

As you know a projection view from a point can be expressed with different sets of Euler angles. This function gives you another expression of the Euler angles for this point of view. Exactly the operation performed is:

newrot = rot + 180;
newtilt = -tilt;
newpsi = -180 + psi;
Euler_another_set(rot, tilt, psi, newrot, newtilt, newpsi);

Definition at line 1002 of file geometry.cpp.

1004 {
1005  newrot = rot + 180;
1006  newtilt = -tilt;
1007  newpsi = -180 + psi;
1008 }
double psi(const double x)

◆ Euler_apply_transf()

void Euler_apply_transf ( const Matrix2D< double > &  L,
const Matrix2D< double > &  R,
double  rot,
double  tilt,
double  psi,
double &  newrot,
double &  newtilt,
double &  newpsi 
)

Apply a geometrical transformation

The idea behind this function is the following. 3 Euler angles define a point of view for a projection, but also a coordinate system. You might apply a geometrical transformation to this system, and then compute back what the Euler angles for the new system are. This could be used to "mirror" points of view, rotate them and all the stuff. The transformation matrix must be 3x3 but it must transform R3 vectors into R3 vectors (that is a normal 3D transformation matrix when vector coordinates are not homogeneous) and it will be applied in the sense:

New Euler matrix = L * Old Euler matrix * R

where you know that the Euler matrix rows represent the different system axes. See Euler_angles2matrix for more information about the Euler coordinate system.

R60.resize(3, 3); // Get rid of homogeneous part
I.initIdentity();
Euler_apply_transf(I, R60, rot, tilt, psi, newrot, newtilt, newpsi);

Definition at line 1038 of file geometry.cpp.

1046 {
1047 
1048  Matrix2D<double> euler(3, 3), temp;
1049  Euler_angles2matrix(rot, tilt, psi, euler);
1050  temp = L * euler * R;
1051  Euler_matrix2angles(temp, newrot, newtilt, newpsi);
1052 }
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
double psi(const double x)
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839

◆ Euler_direction()

void Euler_direction ( double  alpha,
double  beta,
double  gamma,
Matrix1D< double > &  v 
)

Euler direction

This function returns a vector parallel to the projection direction. Resizes v if needed

Definition at line 721 of file geometry.cpp.

723 {
724  double ca, sa, cb, sb;
725  double sc, ss;
726 
727  v.resize(3);
728  alpha = DEG2RAD(alpha);
729  beta = DEG2RAD(beta);
730 
731  ca = cos(alpha);
732  cb = cos(beta);
733  sa = sin(alpha);
734  sb = sin(beta);
735  sc = sb * ca;
736  ss = sb * sa;
737 
738  v(0) = sc;
739  v(1) = ss;
740  v(2) = cb;
741 }
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
double beta(const double a, const double b)
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410

◆ Euler_direction2angles()

void Euler_direction2angles ( Matrix1D< double > &  v,
double &  alpha,
double &  beta,
double &  gamma 
)

Euler direction2angles

This function returns the 3 Euler angles associated to the direction given by the vector v. The 3rd Euler angle is set always to 0

Definition at line 746 of file geometry.cpp.

748 {
749  double abs_ca, sb, cb;
750  double aux_alpha;
751  double aux_beta;
752  double error, newerror;
753  Matrix1D<double> v_aux;
755 
756  //if not normalized do it so
757  v.resize(3);
758  v = v0;
759  v.selfNormalize();
760 
761  v_aux.resize(3);
762  cb = v(2);
763 
764  if (fabs((cb)) > 0.999847695)/*one degree */
765  {
766  std::cerr << "\nWARNING: Routine Euler_direction2angles is not reliable\n"
767  "for small tilt angles. Up to 0.001 deg it should be OK\n"
768  "for most applications but you never know";
769  }
770 
771  if (fabs((cb - 1.)) < FLT_EPSILON)
772  {
773  alpha = 0.;
774  beta = 0.;
775  }
776  else
777  {/*1*/
778 
779  aux_beta = acos(cb); /* beta between 0 and PI */
780 
781 
782  sb = sin(aux_beta);
783 
784  abs_ca = fabs(v(0)) / sb;
785  if (fabs((abs_ca - 1.)) < FLT_EPSILON)
786  aux_alpha = 0.;
787  else
788  aux_alpha = acos(abs_ca);
789 
790  v_aux(0) = sin(aux_beta) * cos(aux_alpha);
791  v_aux(1) = sin(aux_beta) * sin(aux_alpha);
792  v_aux(2) = cos(aux_beta);
793 
794  error = fabs(dotProduct(v, v_aux) - 1.);
795  alpha = aux_alpha;
796  beta = aux_beta;
797 
798  v_aux(0) = sin(aux_beta) * cos(-1. * aux_alpha);
799  v_aux(1) = sin(aux_beta) * sin(-1. * aux_alpha);
800  v_aux(2) = cos(aux_beta);
801  newerror = fabs(dotProduct(v, v_aux) - 1.);
802  if (error > newerror)
803  {
804  alpha = -1. * aux_alpha;
805  beta = aux_beta;
806  error = newerror;
807  }
808 
809  v_aux(0) = sin(-aux_beta) * cos(-1. * aux_alpha);
810  v_aux(1) = sin(-aux_beta) * sin(-1. * aux_alpha);
811  v_aux(2) = cos(-aux_beta);
812  newerror = fabs(dotProduct(v, v_aux) - 1.);
813  if (error > newerror)
814  {
815  alpha = -1. * aux_alpha;
816  beta = -1. * aux_beta;
817  error = newerror;
818  }
819 
820  v_aux(0) = sin(-aux_beta) * cos(aux_alpha);
821  v_aux(1) = sin(-aux_beta) * sin(aux_alpha);
822  v_aux(2) = cos(-aux_beta);
823  newerror = fabs(dotProduct(v, v_aux) - 1.);
824 
825  if (error > newerror)
826  {
827  alpha = aux_alpha;
828  beta = -1. * aux_beta;
829  }
830  }/*else 1 end*/
831  gamma = 0.;
832  beta = RAD2DEG(beta);
833  alpha = RAD2DEG(alpha);
834 }/*Eulerdirection2angles end*/
double beta(const double a, const double b)
void selfNormalize()
Definition: matrix1d.cpp:723
double * gamma
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define FLT_EPSILON
Definition: geometry.h:33
void error(char *s)
Definition: tools.cpp:107
T dotProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1140
#define RAD2DEG(r)
Definition: xmipp_macros.h:320
double v0

◆ Euler_distanceBetweenAngleSets()

template<typename T >
T Euler_distanceBetweenAngleSets ( rot1,
tilt1,
psi1,
rot2,
tilt2,
psi2,
bool  only_projdir 
)

Average distance between two angle sets. If the only_projdir is set, then only the projection direction is considered.

Definition at line 681 of file geometry.cpp.

684 {
685  static_assert(std::is_floating_point<T>::value, "Only float and double are allowed as template parameters");
686 
687  Matrix2D<T> E1, E2;
688  Euler_angles2matrix(rot1, tilt1, psi1, E1, false);
689  return Euler_distanceBetweenAngleSets_fast(E1,rot2,tilt2,psi2,only_projdir,E2);
690 }
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
Definition: mask.h:36
T Euler_distanceBetweenAngleSets_fast(const Matrix2D< T > &E1, T rot2, T tilt2, T psi2, bool only_projdir, Matrix2D< T > &E2)
Definition: geometry.cpp:693

◆ Euler_distanceBetweenAngleSets_fast()

template<typename T >
T Euler_distanceBetweenAngleSets_fast ( const Matrix2D< T > &  E1,
rot2,
tilt2,
psi2,
bool  only_projdir,
Matrix2D< T > &  E2 
)

Average distance between two angle sets. E1 must contain the Euler matrix corresponding to set1, E2 is used as an auxiliary variable for storing the second Euler matrix.

Definition at line 693 of file geometry.cpp.

696 {
697  static_assert(std::is_floating_point<T>::value, "Only float and double are allowed as template parameters");
698 
699  Euler_angles2matrix(rot2, tilt2, psi2, E2, false);
700  T aux=MAT_ELEM(E1,2,0)*MAT_ELEM(E2,2,0)+
701  MAT_ELEM(E1,2,1)*MAT_ELEM(E2,2,1)+
702  MAT_ELEM(E1,2,2)*MAT_ELEM(E2,2,2);
703  T axes_dist=std::acos(CLIP(aux, -1, 1));
704  if (!only_projdir)
705  {
706  for (int i = 0; i < 2; i++)
707  {
708  T aux=MAT_ELEM(E1,i,0)*MAT_ELEM(E2,i,0)+
709  MAT_ELEM(E1,i,1)*MAT_ELEM(E2,i,1)+
710  MAT_ELEM(E1,i,2)*MAT_ELEM(E2,i,2);
711  T dist=acos(CLIP(aux, -1, 1));
712  axes_dist += dist;
713  }
714  axes_dist /= 3.0;
715  }
716  return RAD2DEG(axes_dist);
717 }
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
#define i
#define CLIP(x, x0, xF)
Definition: xmipp_macros.h:260
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
#define RAD2DEG(r)
Definition: xmipp_macros.h:320

◆ Euler_distanceBetweenMatrices()

double Euler_distanceBetweenMatrices ( const Matrix2D< double > &  E1,
const Matrix2D< double > &  E2 
)

Distance between two Euler matrices.

The distance is defined as 1/3*(X1.X2 + Y1.Y2 + Z1.Z2)

Definition at line 671 of file geometry.cpp.

673 {
674  double retval=0;
676  retval+=MAT_ELEM(E1,i,j)*MAT_ELEM(E2,i,j);
677  return retval/3.0;
678 }
#define FOR_ALL_ELEMENTS_IN_MATRIX2D(m)
Definition: matrix2d.h:104
#define i
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
#define j

◆ Euler_matrix2angles()

void Euler_matrix2angles ( const Matrix2D< double > &  A,
double &  alpha,
double &  beta,
double &  gamma,
bool  homogeneous = false 
)

"Euler" matrix –> angles

This function compute a set of Euler angles which result in an "Euler" matrix as the one given. See Euler_angles2matrix to know more about how this matrix is computed and what each row means. The result angles are in degrees. Alpha, beta and gamma are respectively the first, second and third rotation angles. If the input matrix is not 3x3 then an exception is thrown, the function doesn't check that the Euler matrix is truly representing a coordinate system.

Definition at line 839 of file geometry.cpp.

841 {
842  double abs_sb, sign_sb;
843 
844  if (homogeneous)
845  if (MAT_XSIZE(A) != 4 || MAT_YSIZE(A) != 4)
846  REPORT_ERROR(ERR_MATRIX_SIZE, "Euler_matrix2angles: The Euler matrix is not 4x4");
847  else
848  if (MAT_XSIZE(A) != 3 || MAT_YSIZE(A) != 3)
849  REPORT_ERROR(ERR_MATRIX_SIZE, "Euler_matrix2angles: The Euler matrix is not 3x3");
850 
851  abs_sb = sqrt(A(0, 2) * A(0, 2) + A(1, 2) * A(1, 2));
852  if (abs_sb > 16*FLT_EPSILON)
853  {
854  gamma = atan2(A(1, 2), -A(0, 2));
855  alpha = atan2(A(2, 1), A(2, 0));
856  if (ABS(sin(gamma)) < FLT_EPSILON)
857  sign_sb = SGN(-A(0, 2) / cos(gamma));
858  // if (sin(alpha)<FLT_EPSILON) sign_sb=SGN(-A(0,2)/cos(gamma));
859  // else sign_sb=(sin(alpha)>0) ? SGN(A(2,1)):-SGN(A(2,1));
860  else
861  sign_sb = (sin(gamma) > 0) ? SGN(A(1, 2)) : -SGN(A(1, 2));
862  beta = atan2(sign_sb * abs_sb, A(2, 2));
863  }
864  else
865  {
866  if (SGN(A(2, 2)) > 0)
867  {
868  // Let's consider the matrix as a rotation around Z
869  alpha = 0;
870  beta = 0;
871  gamma = atan2(-A(1, 0), A(0, 0));
872  }
873  else
874  {
875  alpha = 0;
876  beta = PI;
877  gamma = atan2(A(1, 0), -A(0, 0));
878  }
879  }
880 
881  gamma = RAD2DEG(gamma);
882  beta = RAD2DEG(beta);
883  alpha = RAD2DEG(alpha);
884 
885 #ifdef double
886 
887  Matrix2D<double> Ap;
888  Euler_angles2matrix(alpha, beta, gamma, Ap);
889  if (A != Ap)
890  {
891  std::cout << "---\n";
892  std::cout << "Euler_matrix2angles: I have computed angles "
893  " which doesn't match with the original matrix\n";
894  std::cout << "Original matrix\n" << A;
895  std::cout << "Computed angles alpha=" << alpha << " beta=" << beta
896  << " gamma=" << gamma << std::endl;
897  std::cout << "New matrix\n" << Ap;
898  std::cout << "---\n";
899  }
900 #endif
901 
902 #ifdef DEBUG
903  std::cout << "abs_sb " << abs_sb << std::endl;
904  std::cout << "A(1,2) " << A(1, 2) << " A(0,2) " << A(0, 2) << " gamma "
905  << gamma << std::endl;
906  std::cout << "A(2,1) " << A(2, 1) << " A(2,0) " << A(2, 0) << " alpha "
907  << alpha << std::endl;
908  std::cout << "sign sb " << sign_sb << " A(2,2) " << A(2, 2)
909  << " beta " << beta << std::endl;
910 #endif
911 }
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Problem with matrix size.
Definition: xmipp_error.h:152
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
double beta(const double a, const double b)
void sqrt(Image< double > &op)
double * gamma
#define ABS(x)
Definition: xmipp_macros.h:142
#define FLT_EPSILON
Definition: geometry.h:33
#define RAD2DEG(r)
Definition: xmipp_macros.h:320
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
#define PI
Definition: tools.h:43
#define SGN(x)
Definition: xmipp_macros.h:155

◆ Euler_mirrorX()

void Euler_mirrorX ( double  rot,
double  tilt,
double  psi,
double &  newrot,
double &  newtilt,
double &  newpsi 
)

Mirror over X axis

Given a set of Euler angles this function returns a new set which define a mirrored (over X axis) version of the former projection.

-----> X Y
| ^
| |
| ======> |
v |
Y -----> X

The operation performed is

newrot = rot;
newtilt = tilt + 180;
newpsi = 180 - psi;
Euler_mirrorX(rot, tilt, psi, newrot, newtilt, newpsi);

Definition at line 1020 of file geometry.cpp.

1022 {
1023  newrot = rot;
1024  newtilt = tilt + 180;
1025  newpsi = 180 - psi;
1026 }
double psi(const double x)

◆ Euler_mirrorXY()

void Euler_mirrorXY ( double  rot,
double  tilt,
double  psi,
double &  newrot,
double &  newtilt,
double &  newpsi 
)

Mirror over X and Y axes

Given a set of Euler angles this function returns a new set which define a mirrored (over X and Y axes at the same time) version of the former projection.

-----> X Y
| ^
| |
| ======> |
v |
Y X<-----

The operation performed is

newrot = rot;
newtilt = tilt;
newpsi = 180 + psi;
Euler_mirrorX(rot, tilt, psi, newrot, newtilt, newpsi);

Definition at line 1029 of file geometry.cpp.

1031 {
1032  newrot = rot;
1033  newtilt = tilt;
1034  newpsi = 180 + psi;
1035 }
double psi(const double x)

◆ Euler_mirrorY()

void Euler_mirrorY ( double  rot,
double  tilt,
double  psi,
double &  newrot,
double &  newtilt,
double &  newpsi 
)

Mirror over Y axis

Given a set of Euler angles this function returns a new set which define a mirrored (over Y axis) version of the former projection.

-----> X X<------
| |
| |
| ======> |
v v
Y Y

The operation performed is

newrot = rot;
newtilt = tilt + 180;
newpsi = -psi;
Euler_mirrorY(rot, tilt, psi, newrot, newtilt, newpsi);

Definition at line 1011 of file geometry.cpp.

1013 {
1014  newrot = rot;
1015  newtilt = tilt + 180;
1016  newpsi = -psi;
1017 }
double psi(const double x)

◆ Euler_rotate() [1/2]

void Euler_rotate ( const MultidimArray< double > &  V,
double  rot,
double  tilt,
double  psi,
MultidimArray< double > &  result 
)

Rotate a volume after 3 Euler angles

Input and output volumes cannot be the same one.

Definition at line 1061 of file geometry.cpp.

1063 {
1064  Matrix2D<double> R;
1065  Euler_angles2matrix(rot, tilt, psi, R, true);
1066  applyGeometry(1, result, V, R, xmipp_transformation::IS_NOT_INV, xmipp_transformation::DONT_WRAP);
1067 }
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
double psi(const double x)

◆ Euler_rotate() [2/2]

void Euler_rotate ( const MultidimArrayGeneric V,
double  rot,
double  tilt,
double  psi,
MultidimArray< double > &  result 
)

Rotate a volume after 3 Euler angles

Input and output volumes cannot be the same one.

Definition at line 1068 of file geometry.cpp.

1070 {
1071  Matrix2D<double> R;
1072  Euler_angles2matrix(rot, tilt, psi, R, true);
1073 #define APPLYGEO(type) applyGeometry(1, result, *((MultidimArray<type> *)V.im), R, xmipp_transformation::IS_NOT_INV, xmipp_transformation::DONT_WRAP);
1075 #undef APPLYGEO
1076 }
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
#define APPLYGEO(type)
double psi(const double x)
#define SWITCHDATATYPE(datatype, OP)

◆ Euler_up_down()

void Euler_up_down ( double  rot,
double  tilt,
double  psi,
double &  newrot,
double &  newtilt,
double &  newpsi 
)

Up-Down projection equivalence

As you know a projection view from a point has got its homologous from its diametrized point in the projection sphere. This function takes a projection defined by its 3 Euler angles and computes an equivalent set of Euler angles from which the view is exactly the same but in the other part of the sphere (if the projection is taken from the bottom then the new projection from the top, and viceversa). The defined projections are exactly the same except for a flip over X axis, ie, an up-down inversion. Exactly the correction performed is:

newrot = rot;
newtilt = tilt + 180;
newpsi = -(180 + psi);
Euler_up_down(rot, tilt, psi, newrot, newtilt, newpsi);

Definition at line 993 of file geometry.cpp.

995 {
996  newrot = rot;
997  newtilt = tilt + 180;
998  newpsi = -(180 + psi);
999 }
double psi(const double x)

◆ intersection_unit_cube()

double intersection_unit_cube ( const Matrix1D< double > &  u,
const Matrix1D< double > &  r 
)

Intersection of a ray with a unit cube

The cube is centered at (0,0,0) and has got unit size length in all directions, i.e., the cube goes from (-0.5, -0.5, -0.5) to (0.5, 0.5, 0.5). The ray is defined by its direction (u) and a passing point (r). See Cube to know how you can intersect any ray with any cube.

Definition at line 1190 of file geometry.cpp.

1193 {
1194  double t1=0., t2=0., t;
1195  int found_t = 0;
1196 
1197 #define ASSIGN_IF_GOOD_ONE \
1198  if (fabs(XX(r)+t*XX(u))-XMIPP_EQUAL_ACCURACY<=0.5 && \
1199  fabs(YY(r)+t*YY(u))-XMIPP_EQUAL_ACCURACY<=0.5 && \
1200  fabs(ZZ(r)+t*ZZ(u))-XMIPP_EQUAL_ACCURACY<=0.5) {\
1201  if (found_t==0) {found_t++; t1=t;} \
1202  else if (found_t==1) {found_t++; t2=t;} \
1203  }
1204 
1205  // Intersect with x=0.5 and x=-0.5
1206  if (XX(u) != 0)
1207  {
1208  t = (0.5 - XX(r)) / XX(u);
1210  t = (-0.5 - XX(r)) / XX(u);
1212  }
1213 
1214  // Intersect with y=0.5 and y=-0.5
1215  if (YY(u) != 0 && found_t != 2)
1216  {
1217  t = (0.5 - YY(r)) / YY(u);
1219  t = (-0.5 - YY(r)) / YY(u);
1221  }
1222 
1223  // Intersect with z=0.5 and z=-0.5
1224  if (ZZ(u) != 0 && found_t != 2)
1225  {
1226  t = (0.5 - ZZ(r)) / ZZ(u);
1228  t = (-0.5 - ZZ(r)) / ZZ(u);
1230  }
1231 
1232  if (found_t == 2)
1233  return fabs(t1 -t2);
1234  else
1235  return 0;
1236 }
#define ASSIGN_IF_GOOD_ONE
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ intersection_unit_cylinder()

double intersection_unit_cylinder ( const Matrix1D< double > &  u,
const Matrix1D< double > &  r 
)

Intersection of a ray with a unit cylinder

The cylinder is centered at (0,0,0), has got unit radius on the plane XY, and in Z goes from -h/2 to +h/2. The ray is defined by its direction (u) and a passing point (r). If the ray belongs to the lateral circular wall of the cylinder the length returned is h (h is computed as 1/ZZ(u), this is so because it is supposed that this intersection is computed after a coordinate transformation process from any cylinder to a unit one).

See Cylinder to know how you can intersect any ray with any cylinder.

Definition at line 1151 of file geometry.cpp.

1154 {
1155  // Intersect with an infinite cylinder of radius=ry
1156  double A = XX(u) * XX(u) + YY(u) * YY(u);
1157  double B = XX(r) * XX(u) + YY(r) * YY(u);
1158  double C = XX(r) * XX(r) + YY(r) * YY(r) - 1;
1159 
1160  double B2_AC = B * B - A * C;
1161  if (A == 0)
1162  {
1163  if (C > 0)
1164  return 0; // Parallel ray outside the cylinder
1165  else
1166  return 1 / ZZ(u); // return height
1167  }
1168  else if (B2_AC < 0)
1169  return 0;
1170  B2_AC = sqrt(B2_AC);
1171 
1172  // Points at intersection
1173  double t1 = (-B - B2_AC) / A;
1174  double t2 = (-B + B2_AC) / A;
1175  double z1 = ZZ(r) + t1 * ZZ(u);
1176  double z2 = ZZ(r) + t2 * ZZ(u);
1177 
1178  // Check position of the intersecting points with respect to
1179  // the finite cylinder, if any is outside correct it to the
1180  // right place in the top or bottom of the cylinder
1181  if (ABS(z1) >= 0.5)
1182  t1 = (SGN(z1) * 0.5 - ZZ(r)) / ZZ(u);
1183  if (ABS(z2) >= 0.5)
1184  t2 = (SGN(z2) * 0.5 - ZZ(r)) / ZZ(u);
1185 
1186  return ABS(t1 -t2);
1187 }
void sqrt(Image< double > &op)
#define XX(v)
Definition: matrix1d.h:85
#define ABS(x)
Definition: xmipp_macros.h:142
#define YY(v)
Definition: matrix1d.h:93
#define SGN(x)
Definition: xmipp_macros.h:155
#define ZZ(v)
Definition: matrix1d.h:101

◆ intersection_unit_sphere()

double intersection_unit_sphere ( const Matrix1D< double > &  u,
const Matrix1D< double > &  r 
)

Intersection of a ray with a unit sphere

The sphere is centered at (0,0,0) and has got unit radius. The ray is defined by its direction (u) and a passing point (r). The function returns the length of the intersection. If the ray is tangent to the sphere the length is 0. See Ellipsoid to know how you can intersect any ray with any ellipsoid/sphere.

Definition at line 1122 of file geometry.cpp.

1125 {
1126 
1127  // Some useful constants
1128  double A = XX(u) * XX(u) + YY(u) * YY(u) + ZZ(u) * ZZ(u);
1129  double B = XX(r) * XX(u) + YY(r) * YY(u) + ZZ(r) * ZZ(u);
1130  double C = XX(r) * XX(r) + YY(r) * YY(r) + ZZ(r) * ZZ(r) - 1.0;
1131  double B2_AC = B * B - A * C;
1132 
1133  // A degenerate case?
1134  if (A == 0)
1135  {
1136  if (B == 0)
1137  return -1; // The ellipsoid doesn't intersect
1138  return 0; // The ellipsoid is tangent at t=-C/2B
1139  }
1140  if (B2_AC < 0)
1141  return -1;
1142 
1143  // A normal intersection
1144  B2_AC = sqrt(B2_AC);
1145  double t1 = (-B - B2_AC) / A; // The two parameters within the line for
1146  double t2 = (-B + B2_AC) / A; // the solution
1147  return ABS(t2 -t1);
1148 }
void sqrt(Image< double > &op)
#define XX(v)
Definition: matrix1d.h:85
#define ABS(x)
Definition: xmipp_macros.h:142
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ least_squares_line_fit()

void least_squares_line_fit ( const std::vector< fit_point2D > &  IN_points,
double &  line_A,
double &  line_B 
)

Least-squares-fit a line to an arbitrary number of (x,y) points

Plane described as Ax + B = y

Points are defined using the struct

{
double x;
double y;
double w;
};

where w is a weighting factor. Set it to 1 if you do not want to use it

Definition at line 212 of file geometry.cpp.

215 {
216 
217  double sumx = 0.;
218  double sumy = 0.;
219  double sumxy = 0.;
220  double sumxx = 0.;
221  double sumw = 0.;
222  double W2;
223  const fit_point2D * point;
224 
225  int n = IN_points.size();
226 
227  for (int i = 0; i < n; i++)
228  {
229  point = &(IN_points[i]);
230  W2 = point->w * point->w;
231  sumx += point->x * point->w ;
232  sumy += point->y * point->w ;
233  sumxx += point->x * point->x * W2 ;
234  sumxy += point->x * point->y * W2 ;
235  sumw += point->w ;
236  }
237  line_a = (sumx*sumy - sumw*sumxy) / (sumx*sumx - sumw*sumxx) ;
238  line_b = (sumy - line_a*sumx) / sumw ;
239 }
double x
x coordinate
Definition: geometry.h:234
#define i
double y
y coordinate (assumed to be a function of x)
Definition: geometry.h:236
double w
Weight of the point in the Least-Squares problem.
Definition: geometry.h:238
int * n

◆ least_squares_plane_fit()

void least_squares_plane_fit ( FitPoint IN_points,
int  Npoints,
double &  plane_A,
double &  plane_B,
double &  plane_C 
)

Least-squares-fit a plane to an arbitrary number of (x,y,z) points

Plane described as Ax + By + C = z

Points are defined using the struct

struct fit_point
{
double x;
double y;
double z;
double w;
};

where w is a weighting factor. Set it to 1 if you do not want to use it

Definition at line 101 of file geometry.cpp.

106 {
107  double D = 0;
108  double E = 0;
109  double F = 0;
110  double G = 0;
111  double H = 0;
112  double I = 0;
113  double J = 0;
114  double K = 0;
115  double L = 0;
116  double W2 = 0;
117  double denom = 0;
118  const FitPoint * point;
119 
120  for (int i = 0; i < Npoints; i++)
121  {
122  point = &(IN_points[i]);//Can I copy just the address?
123  W2 = point->w * point->w;
124  D += point->x * point->x * W2 ;
125  E += point->x * point->y * W2 ;
126  F += point->x * W2 ;
127  G += point->y * point->y * W2 ;
128  H += point->y * W2 ;
129  I += 1 * W2 ;
130  J += point->x * point->z * W2 ;
131  K += point->y * point->z * W2 ;
132  L += point->z * W2 ;
133  }
134 
135  denom = F * F * G - 2 * E * F * H + D * H * H + E * E * I - D * G * I;
136 
137  // X axis slope
138  plane_a = (H * H * J - G * I * J + E * I * K + F * G * L - H * (F * K + E * L)) / denom;
139  // Y axis slope
140  plane_b = (E * I * J + F * F * K - D * I * K + D * H * L - F * (H * J + E * L)) / denom;
141  // Z axis intercept
142  plane_c = (F * G * J - E * H * J - E * F * K + D * H * K + E * E * L - D * G * L) / denom;
143 }
double z
z coordinate, assumed to be a function of x and y
Definition: geometry.h:190
double x
x coordinate
Definition: geometry.h:186
double w
Weight of the point in the Least-Squares problem.
Definition: geometry.h:192
#define i
double y
y coordinate
Definition: geometry.h:188
constexpr int K

◆ least_squares_plane_fit_All_Points()

void least_squares_plane_fit_All_Points ( const MultidimArray< double > &  Image,
double &  plane_A,
double &  plane_B,
double &  plane_C 
)

Least-squares-fit a plane to an image

Performs the same computation as least_squares_plane_fit but using a complete image instead of only a set of points.

Definition at line 154 of file geometry.cpp.

158 {
159  double D = 0;
160  double E = 0;
161  double F = 0;
162  double G = 0;
163  double H = 0;
164  double I = 0;
165  double J = 0;
166  double K = 0;
167  double L = 0;
168  double denom = 0;
169  int nIterations=0;
170  double sumjValues=0.0;
171  for (int j=STARTINGX(Image); j<=FINISHINGX(Image); ++j)
172  {
173  D += j*j;
174  sumjValues += j;
175  I += 1;
176  }
177  F = sumjValues;
178 
179  double *ref;
180  double sumElements;
181  for (int i=STARTINGY(Image); i<=FINISHINGY(Image); ++i)
182  {
183  nIterations++;
184  ref = &A2D_ELEM(Image, i, STARTINGX(Image));
185  sumElements = 0.0;
186  for (int j=STARTINGX(Image); j<=FINISHINGX(Image); ++j)
187  {
188  J += j*(*ref);
189  sumElements += (*ref);
190  ref++;
191  }
192  K += i*sumElements;
193  L += sumElements;
194  E += sumjValues*i;
195  G += i*i*I;
196  H += i*I;
197  }
198  D = D*nIterations;
199  F = F*nIterations;
200  I = I*nIterations;
201 
202  denom = F * F * G - 2 * E * F * H + D * H * H + E * E * I - D * G * I;
203 
204  // X axis slope
205  plane_a = (H * H * J - G * I * J + E * I * K + F * G * L - H * (F * K + E * L)) / denom;
206  // Y axis slope
207  plane_b = (E * I * J + F * F * K - D * I * K + D * H * L - F * (H * J + E * L)) / denom;
208  // Z axis intercept
209  plane_c = (F * G * J - E * H * J - E * F * K + D * H * K + E * E * L - D * G * L) / denom;
210 }
#define A2D_ELEM(v, i, j)
#define FINISHINGX(v)
#define STARTINGX(v)
#define i
#define STARTINGY(v)
#define j
#define FINISHINGY(v)
constexpr int K

◆ line_plane_intersection()

int line_plane_intersection ( const Matrix1D< double >  normal_plane,
const Matrix1D< double >  vector_line,
Matrix1D< double > &  intersection_point,
const Matrix1D< double >  point_line,
double  point_plane_at_x_y_zero = 0. 
)

Line Plane Intersection

Let ax+by+cz+D=0 be the equation of your plane (if your plane is defined by a normal vector N + one point M, then (a,b,c) are the coordinates of the normal N, and d is calculated by using the coordinates of M in the above equation).

Let your line be defined by one point P(d,e,f) and a vector V(u,v,w), the points on your line are those which verify

x = d + lu y = e + lv z = f + lw

where l takes all real values.

for this point to be on the plane, you have to have

ax + by + cz + D = 0, so,

a(d + lu) + b(e + lv) + c(f + lw) + D = 0

that is

l(au + bv + cw) = -(ad + be + cf + D)

note that, if au + bv + cw = 0, then your line is either in the plane, or parallel to it... otherwise you get the value of l, and the intersection has coordinates:

x = d + lu y = e + lv z = f + lw

where

l = -(ad + be + cf + D) / (au + bv + cw)

a = XX(normal_plane); b = YY(normal_plane); c = ZZ(normal_plane); D = intersection_point;

d = XX(point_line) e = YY(point_line) f = ZZ(point_line)

u = XX(vector_line); v = YY(vector_line); w = ZZ(vector_line);

XX(intersection_point) = x; YY(intersection_point) = y; ZZ(intersection_point) = z;

return 0 if successful return -1 if line parallel to plane return +1 if line in the plane

Definition at line 588 of file geometry.cpp.

593 {
594  double l;
595  intersection_point.resize(3);
596  // if au+bv+cw=0, then your line is either in the plane, or
597  // parallel to it
598  if (ABS(dotProduct(normal_plane, vector_line)) < XMIPP_EQUAL_ACCURACY)
599  {
600  intersection_point = point_line + vector_line;
601  if (ABS(dotProduct(intersection_point, normal_plane) +
602  point_plane_at_x_y_zero) < XMIPP_EQUAL_ACCURACY)
603  return(1);
604  else
605  return(-1);
606 
607  }
608  //compute intersection
609  l = -1.0 * dotProduct(point_line, normal_plane) +
610  point_plane_at_x_y_zero;
611  l /= dotProduct(normal_plane, vector_line);
612 
613  intersection_point = point_line + l * vector_line;
614  return(0);
615 }
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define ABS(x)
Definition: xmipp_macros.h:142
T dotProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1140

◆ point_inside_polygon()

bool point_inside_polygon ( const std::vector< Matrix1D< double > > &  polygon,
const Matrix1D< double > &  point 
)

Point inside polygon

Given a polygon described by a list of points (the last one and the first one ust be the same), determine whether another point is inside the polygon or not.

Definition at line 418 of file geometry.cpp.

420 {
421  size_t i, j;
422  bool retval = false;
423  for (i = 0, j = polygon.size() - 1; i < polygon.size(); j = i++)
424  {
425  if ((((YY(polygon[i]) <= YY(point)) && (YY(point) < YY(polygon[j]))) ||
426  ((YY(polygon[j]) <= YY(point)) && (YY(point) < YY(polygon[i])))) &&
427  (XX(point) < (XX(polygon[j]) - XX(polygon[i])) *
428  (YY(point) - YY(polygon[i])) /
429  (YY(polygon[j]) - YY(polygon[i])) + XX(polygon[i])))
430  retval = !retval;
431  }
432  return retval;
433 }
#define i
#define XX(v)
Definition: matrix1d.h:85
#define j
#define YY(v)
Definition: matrix1d.h:93

◆ point_line_distance_3D()

double point_line_distance_3D ( const Matrix1D< double > &  p,
const Matrix1D< double > &  a,
const Matrix1D< double > &  v 
)

Point to line distance in 3D

Let a line in 3-D be specified by the point a and the vector v, this fuction returns the minimum distance of this line to the point p.

Definition at line 85 of file geometry.cpp.

89 {
90  Matrix1D<double> p_a(3);
91 
92  V3_MINUS_V3(p_a, p, a);
93  return (vectorProduct(p_a, v).module() / v.module());
94 }
double module() const
Definition: matrix1d.h:983
#define V3_MINUS_V3(a, b, c)
Definition: matrix1d.h:202
Matrix1D< T > vectorProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1165

◆ point_plane_distance_3D()

double point_plane_distance_3D ( const Matrix1D< double > &  p,
const Matrix1D< double > &  a,
const Matrix1D< double > &  v 
)
inline

Point to plane distance in 3D

Let a plane in 3-D be specified by the point a and the perpendicular vector v, this fuction returns the minimum distance of this plane to the point p.

Definition at line 171 of file geometry.h.

174 {
175  static Matrix1D< double > p_a(3);
176 
177  V3_MINUS_V3(p_a, p, a);
178  return (dotProduct(p_a, v) / v.module());
179 }
double module() const
Definition: matrix1d.h:983
#define V3_MINUS_V3(a, b, c)
Definition: matrix1d.h:202
T dotProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1140

◆ rectangle_enclosing()

void rectangle_enclosing ( const Matrix1D< double > &  v0,
const Matrix1D< double > &  vF,
const Matrix2D< double > &  V,
Matrix1D< double > &  corner1,
Matrix1D< double > &  corner2 
)

Rectangle which encloses a deformed rectangle

Given a rectangle characterized by the top-left corner and the right-bottom corner, and given a matrix after which the rectangle is deformed. Which is the minimum rectangle which encloses the preceding one? This function is useful for stablishing for loops which will cover for sure the deformed rectangle. All vectors are supposed to be 2x1 and the deformation matrix is 2x2. The corner (x0,y0) goes to V*(x0,y0)' and (xF,yF) to V*(xf,yF)'. After that you can make a loop from corner1 to corner2.

The v0 and vF vectors can be reused as outputs.

Definition at line 328 of file geometry.cpp.

331 {
333  Matrix1D<double> v(2);
334  corner1.resize(2);
335  corner2.resize(2);
336 
337  // Store values for reusing input as output vectors
338  double XX_v0 = XX(v0);
339  double YY_v0 = YY(v0);
340  double XX_vF = XX(vF);
341  double YY_vF = YY(vF);
342 
343  VECTOR_R2(v, XX_v0, YY_v0);
344  M2x2_BY_V2x1(v, V, v);
345  XX(corner1) = XX(v);
346  XX(corner2) = XX(v);
347  YY(corner1) = YY(v);
348  YY(corner2) = YY(v);
349 
350 #define DEFORM_AND_CHOOSE_CORNERS2D \
351  M2x2_BY_V2x1(v,V,v); \
352  XX(corner1)=XMIPP_MIN(XX(corner1),XX(v)); \
353  XX(corner2)=XMIPP_MAX(XX(corner2),XX(v)); \
354  YY(corner1)=XMIPP_MIN(YY(corner1),YY(v)); \
355  YY(corner2)=XMIPP_MAX(YY(corner2),YY(v));
356 
357  VECTOR_R2(v, XX_vF, YY_v0);
359  VECTOR_R2(v, XX_v0, YY_vF);
361  VECTOR_R2(v, XX_vF, YY_vF);
363 }
#define VECTOR_R2(v, x, y)
Definition: matrix1d.h:112
#define XX(v)
Definition: matrix1d.h:85
#define M2x2_BY_V2x1(a, M, b)
Definition: matrix2d.h:225
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define SPEED_UP_temps01
Definition: xmipp_macros.h:398
#define YY(v)
Definition: matrix1d.h:93
#define DEFORM_AND_CHOOSE_CORNERS2D

◆ spherical_distance()

double spherical_distance ( const Matrix1D< double > &  r1,
const Matrix1D< double > &  r2 
)

Spherical distance

This function returns the distance over a sphere, not the straight line but the line which goes from one point to the other going over the surface of a sphere, supposing that both points lie on the same sphere.

Definition at line 73 of file geometry.cpp.

74 {
75  double r1r2 = XX(r1) * XX(r2) + YY(r1) * YY(r2) + ZZ(r1) * ZZ(r2);
76  double R1 = sqrt(XX(r1) * XX(r1) + YY(r1) * YY(r1) + ZZ(r1) * ZZ(r1));
77  double R2 = sqrt(XX(r2) * XX(r2) + YY(r2) * YY(r2) + ZZ(r2) * ZZ(r2));
78  double argument = r1r2 / (R1 * R2);
79  double ang = acos(CLIP(argument,-1.,1.));
80  double retVal = ang*R1;
81  return retVal;
82 }
void sqrt(Image< double > &op)
#define CLIP(x, x0, xF)
Definition: xmipp_macros.h:260
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
#define ZZ(v)
Definition: matrix1d.h:101

◆ triangle_area()

double triangle_area ( double  x1,
double  y1,
double  x2,
double  y2,
double  x3,
double  y3 
)

Area of a triangle Given the coordinates of three points this function calculates the area of the triangle

Definition at line 511 of file geometry.cpp.

512 {
513  double trigarea = ((x2 - x1)*(y3 - y1) - (x3 - x1)*(y2 - y1))/2;
514  return (trigarea > 0) ? trigarea : -trigarea;
515 }

◆ Uproject_to_plane() [1/3]

void Uproject_to_plane ( const Matrix1D< double > &  point,
const Matrix1D< double > &  direction,
double  distance,
Matrix1D< double > &  result 
)

Project a point to a plane (direction vector, distance)

Given the coordinates for a vector in R3, and a plane (defined by its direction vector and the minimum distance from the plane to the coordinate system origin). This function computes the perpendicular projection from the vector to the plane. This function has tried to be optimized in speed as it is used in core routines within huge loops, this is why the result is given as an argument, and why no check about the dimensionality of the vectors is performed. The routine performs faster if the result vector is already in R3.

The following example projects the point P=(1,1,1) to the XY-plane storing the result in Pp (belonging to R3), the result is obviously Pp=(1,1,0).

Matrix1D< double > Z = vectorR3(0, 0, 1), P = vector_R3(1, 1, 1), Pp(3);
std::cout << "After projecting: Pp=" << Pp.transpose() << std::endl;

The starting U in the function name stands for the fact that the plane and the point are in the same reference system (called by default Universal).

The result and point vectors can be the same one.

Definition at line 39 of file geometry.cpp.

42 {
43 
44  if (result.size() != 3)
45  result.resize(3);
46  double xx = distance - (XX(point) * XX(direction) + YY(point) * YY(direction) +
47  ZZ(point) * ZZ(direction));
48  XX(result) = XX(point) + xx * XX(direction);
49  YY(result) = YY(point) + xx * YY(direction);
50  ZZ(result) = ZZ(point) + xx * ZZ(direction);
51 }
size_t size() const
Definition: matrix1d.h:508
#define XX(v)
Definition: matrix1d.h:85
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define YY(v)
Definition: matrix1d.h:93
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
#define ZZ(v)
Definition: matrix1d.h:101

◆ Uproject_to_plane() [2/3]

void Uproject_to_plane ( const Matrix1D< double > &  r,
double  rot,
double  tilt,
double  psi,
Matrix1D< double > &  result 
)

Project a vector to a plane (Euler angles)

These planes are restricted to have 0 distance to the universal coordinate system. In this special case, a plane can be defined by 3 Euler angles (this is specially suited for projections, where the projection plane is defined by its 3 Euler angles). Then, the coordinate system associated to the 3 Euler angles (let's call its vectors X',Y',Z') defines a projection plane where Z' is the direction vector, and X'Y' are in-plane vectors. Actually, X' coincides with the X vector in the Matrix2D definition and Y' with the Y vector.

The resulting vector is in R3, and the function has been optimized for speed, so the result is passed as a parameter. This function is based in the one which projects a point given the Euler matrix of the projection plane. If you are to project several points to the same plane, you should better use the project to plane function where you give the Euler matrix.

The following example projects the point P=(1,1,1) to the XY-plane storing the result in Pp (belonging to R3), the result is obviously Pp=(1,1,0).

Matrix1D< double > P = vectorR3(1, 1, 1), Pp(3);
Uproject_to_plane(P, 0, 0, 0, Pp);
std::cout << "After projecting: Pp=" << Pp.transpose() << std::endl;

The starting U in the function name stands for the fact that the plane, and the point are in the same reference system (called by default Universal).

The result and point vectors can be the same one.

Definition at line 54 of file geometry.cpp.

56 {
57  Matrix2D<double> euler(3, 3);
58  Euler_angles2matrix(rot, tilt, psi, euler);
59  Uproject_to_plane(r, euler, result);
60 }
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
double psi(const double x)
void Uproject_to_plane(const Matrix1D< double > &point, const Matrix1D< double > &direction, double distance, Matrix1D< double > &result)
Definition: geometry.cpp:39

◆ Uproject_to_plane() [3/3]

void Uproject_to_plane ( const Matrix1D< double > &  r,
const Matrix2D< double > &  euler,
Matrix1D< double > &  result 
)

Project a vector to a plane (Euler matrix)

These planes are restricted to have 0 distance to the universal coordinate system. In this special case, a plane can be defined by 3 Euler angles (this is specially suited for projections, where the projection plane is defined by its 3 Euler angles). Then, the coordinate system associated to the 3 Euler angles (let's call its vectors X',Y',Z') defines a projection plane where Z' is the direction vector, and X'Y' are in-plane vectors. Actually, X' coincides with the X vector in the Matrix2D definition and Y' with the Y vector.

The resulting vector is in R3, and the function has been optimized for speed, if the result vector is already 3 dimensional when entering the function, no resize is performed; and the result is passed as a parameter. If you are to project several points to the same plane, you should better use the project to plane function where you give the Euler matrix.

The following example projects the point P=(1,1,1) to the XY-plane storing the result in Pp (belonging to R3), the result is obviously Pp=(1,1,0).

Matrix1D< double > P = vectorR3(1, 1, 1), Pp(3);
Euler_angles2matrix(0, 0, 0, euler);
Uproject_to_plane(P, euler, Pp);
std::cout << "After projecting: Pp=" << Pp.transpose() << std::endl;

The starting U in the function name stands for the fact that the plane, and the point are in the same reference system (called by default Universal).

The result and point vectors can be the same one.

Definition at line 63 of file geometry.cpp.

65 {
67  if (VEC_XSIZE(result) != 3)
68  result.resize(3);
69  M3x3_BY_V3x1(result, euler, r);
70 }
#define VEC_XSIZE(m)
Definition: matrix1d.h:77
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
#define M3x3_BY_V3x1(a, M, b)
Definition: matrix2d.h:170
#define SPEED_UP_temps012
Definition: xmipp_macros.h:403