LCOV - code coverage report
Current view: top level - util - CubitTransformMatrix.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 101 245 41.2 %
Date: 2020-06-30 00:58:45 Functions: 11 25 44.0 %
Branches: 100 448 22.3 %

           Branch data     Line data    Source code
       1                 :            : //       Class: CubitTransformMatrix
       2                 :            : //
       3                 :            : // Description: A 4-Dimensional Matrix.  Essentially the same as
       4                 :            : //              a generic CubitMatrix, except that it has some
       5                 :            : //              extra 3D transformation functions.
       6                 :            : //
       7                 :            : //              All transformations are pre-multiplications,
       8                 :            : //              meaning that M*V will transform a point V
       9                 :            : //              in the same order transformations are applied to M.
      10                 :            : //
      11                 :            : //      Owner: Darryl Melander
      12                 :            : 
      13                 :            : #include "CubitTransformMatrix.hpp"
      14                 :            : #include "CubitMessage.hpp"
      15                 :            : 
      16                 :        884 : CubitTransformMatrix::CubitTransformMatrix() 
      17                 :        884 :     : CubitMatrix(4)
      18                 :            : {
      19                 :            :     // Just creates a 4x4 matrix set to identity
      20                 :        884 : }
      21                 :            : 
      22                 :        411 : CubitTransformMatrix::CubitTransformMatrix(const CubitTransformMatrix& from)
      23                 :        411 :     : CubitMatrix(from)
      24                 :            : {
      25                 :            :     // Just copies it
      26                 :        411 : }
      27                 :            : 
      28                 :            : 
      29                 :       2392 : CubitTransformMatrix::~CubitTransformMatrix()
      30                 :            : {
      31                 :            :     // Just deletes it
      32         [ -  + ]:       1196 : }
      33                 :            : 
      34                 :            : 
      35                 :            : 
      36                 :        433 : CubitTransformMatrix& CubitTransformMatrix::translate(const CubitVector& v)
      37                 :            : {
      38                 :        433 :   return translate(v.x(), v.y(), v.z());
      39                 :            : }
      40                 :            : 
      41                 :            : 
      42                 :        455 : CubitTransformMatrix& CubitTransformMatrix::translate (double x, double y, double z)
      43                 :            : {
      44                 :        455 :   set (0, 3, get(0, 3) + x);
      45                 :        455 :   set (1, 3, get(1, 3) + y);
      46                 :        455 :   set (2, 3, get(2, 3) + z);
      47                 :            :   
      48                 :        455 :   return *this;
      49                 :            : }
      50                 :            : 
      51                 :         11 : CubitTransformMatrix& CubitTransformMatrix::rotate(double degrees,
      52                 :            :                                                    const CubitVector& vector)
      53                 :            : {
      54                 :            :   double angle, ct, st;
      55                 :            :     // Make a copy of vector so we don't have to change it
      56         [ +  - ]:         11 :   CubitVector axis = vector;
      57                 :            :   
      58                 :            :     // Convert degrees to radians
      59                 :         11 :   angle = -degrees * CUBIT_PI/180.0;
      60                 :            :   
      61                 :            :     // Take sin and cos
      62                 :         11 :   ct = cos(angle);
      63                 :         11 :   st = sin(angle);
      64                 :            :   
      65                 :            :     // Normalize the axis vector
      66         [ +  - ]:         11 :   axis.normalize();
      67                 :            :   
      68                 :            :     // Make an identity matrix
      69         [ +  - ]:         11 :   CubitTransformMatrix mat;
      70                 :            :   
      71                 :            :     // Setup some calculations that occur repeatedly
      72                 :         11 :   double one_minus_cos = 1.0 - ct;
      73         [ +  - ]:         11 :   double dx_ct = axis.x() * one_minus_cos;
      74         [ +  - ]:         11 :   double dy_ct = axis.y() * one_minus_cos;
      75         [ +  - ]:         11 :   double dz_ct = axis.z() * one_minus_cos;
      76         [ +  - ]:         11 :   double dx_st = axis.x() * st;
      77         [ +  - ]:         11 :   double dy_st = axis.y() * st;
      78         [ +  - ]:         11 :   double dz_st = axis.z() * st;
      79                 :            :   
      80                 :            :     // Set the values in the matrix
      81 [ +  - ][ +  - ]:         11 :   mat.set(0, 0,     ct + axis.x() * dx_ct);
      82 [ +  - ][ +  - ]:         11 :   mat.set(1, 0, -dz_st + axis.x() * dy_ct);
      83 [ +  - ][ +  - ]:         11 :   mat.set(2, 0,  dy_st + axis.x() * dz_ct);
      84                 :            :   
      85 [ +  - ][ +  - ]:         11 :   mat.set(0, 1,  dz_st + axis.y() * dx_ct);
      86 [ +  - ][ +  - ]:         11 :   mat.set(1, 1,     ct + axis.y() * dy_ct);
      87 [ +  - ][ +  - ]:         11 :   mat.set(2, 1, -dx_st + axis.y() * dz_ct);
      88                 :            :   
      89 [ +  - ][ +  - ]:         11 :   mat.set(0, 2, -dy_st + axis.z() * dx_ct);
      90 [ +  - ][ +  - ]:         11 :   mat.set(1, 2,  dx_st + axis.z() * dy_ct);
      91 [ +  - ][ +  - ]:         11 :   mat.set(2, 2,     ct + axis.z() * dz_ct);
      92                 :            :   
      93                 :            :     // Premultiply the matrix
      94 [ +  - ][ +  - ]:         11 :   *this = mat * *this;
                 [ +  - ]
      95                 :            :     // Return
      96         [ +  - ]:         11 :   return *this;
      97                 :            : }
      98                 :            : 
      99                 :          0 : CubitTransformMatrix& CubitTransformMatrix::rotate(double degrees, char axis)
     100                 :            : {
     101 [ #  # ][ #  # ]:          0 :   if(axis != 'x' && axis != 'y' && axis != 'z')
                 [ #  # ]
     102 [ #  # ][ #  # ]:          0 :     throw std::invalid_argument("Invalid Axis: must be X, Y, or Z");
     103                 :            :   //assert (axis == 'x' || axis == 'y' || axis == 'z');
     104                 :            :   
     105                 :            :     // Convert to Radians, Get the sine and cosine
     106                 :          0 :   double angle = degrees * CUBIT_PI/180.;
     107                 :            :   double s, c;
     108                 :          0 :   s = sin(angle);
     109                 :          0 :   c = cos(angle);
     110                 :            :   
     111                 :            :     // Make an Identity matrix
     112         [ #  # ]:          0 :   CubitTransformMatrix mat;
     113                 :            :     // Place values in appropriate places
     114   [ #  #  #  # ]:          0 :   switch (axis)
     115                 :            :   {
     116                 :            :     case 'x':
     117         [ #  # ]:          0 :       mat.set(1, 1, c);
     118         [ #  # ]:          0 :       mat.set(2, 2, c);
     119         [ #  # ]:          0 :       mat.set(1, 2, -s);
     120         [ #  # ]:          0 :       mat.set(2, 1, s);
     121                 :          0 :       break;
     122                 :            :     case 'y':
     123         [ #  # ]:          0 :       mat.set(0, 0, c);
     124         [ #  # ]:          0 :       mat.set(0, 2, s);
     125         [ #  # ]:          0 :       mat.set(2, 0, -s);
     126         [ #  # ]:          0 :       mat.set(2, 2, c);
     127                 :          0 :       break;
     128                 :            :     case 'z':
     129         [ #  # ]:          0 :       mat.set(0, 0, c);
     130         [ #  # ]:          0 :       mat.set(1, 0, s);
     131         [ #  # ]:          0 :       mat.set(0, 1, -s);
     132         [ #  # ]:          0 :       mat.set(1, 1, c);
     133                 :          0 :       break;
     134                 :            :   }
     135                 :            :   
     136                 :            :     // Perform Pre-Multiplication
     137 [ #  # ][ #  # ]:          0 :   *this = mat * *this;
                 [ #  # ]
     138                 :            :   
     139         [ #  # ]:          0 :   return *this;
     140                 :            : }
     141                 :            : 
     142                 :         22 : CubitTransformMatrix& CubitTransformMatrix::reflect(const CubitVector& vector)
     143                 :            : {
     144                 :            :   double a, b, c, d;
     145         [ +  - ]:         22 :   CubitVector axis = vector;
     146         [ +  - ]:         22 :   axis.normalize();
     147                 :            : 
     148         [ +  - ]:         22 :   a = axis.x();
     149         [ +  - ]:         22 :   b = axis.y();
     150         [ +  - ]:         22 :   c = axis.z();
     151                 :            :   
     152                 :         22 :   d = sqrt(b*b + c*c);
     153                 :            :   
     154                 :            :     // Make an Identity matrix
     155         [ +  - ]:         22 :   CubitTransformMatrix mat;
     156         [ +  - ]:         22 :   if(d)
     157                 :            :   {
     158                 :            :       // Place values in appropriate places for negative rotate about x
     159         [ +  - ]:         22 :     mat.set(1, 1, c/d);
     160         [ +  - ]:         22 :     mat.set(1, 2, -b/d);
     161         [ +  - ]:         22 :     mat.set(2, 1, b/d);
     162         [ +  - ]:         22 :     mat.set(2, 2, c/d);
     163                 :            :   
     164                 :            :       // Perform Pre-Multiplication
     165 [ +  - ][ +  - ]:         22 :     *this = mat * *this;
                 [ +  - ]
     166         [ +  - ]:         22 :     mat.set_to_identity();
     167                 :            :   }
     168                 :            :   
     169                 :            :     // Place values in appropriate places for negative rotate about y
     170         [ +  - ]:         22 :   mat.set(0, 0, d);
     171         [ +  - ]:         22 :   mat.set(0, 2, -a);
     172         [ +  - ]:         22 :   mat.set(2, 0, a);
     173         [ +  - ]:         22 :   mat.set(2, 2, d);
     174                 :            : 
     175                 :            :   
     176                 :            :     // Perform Pre-Multiplication
     177 [ +  - ][ +  - ]:         22 :   *this = mat * *this;
                 [ +  - ]
     178         [ +  - ]:         22 :   mat.set_to_identity();
     179                 :            :   
     180                 :            :     // Place values in appropriate places for reflect across z
     181         [ +  - ]:         22 :   mat.set(2, 2, -1);
     182                 :            : 
     183                 :            :   
     184                 :            :     // Perform Pre-Multiplication
     185 [ +  - ][ +  - ]:         22 :   *this = mat * *this;
                 [ +  - ]
     186         [ +  - ]:         22 :   mat.set_to_identity();
     187                 :            :   
     188                 :            :     // Place values in appropriate places for rotate about y
     189         [ +  - ]:         22 :   mat.set(0, 0, d);
     190         [ +  - ]:         22 :   mat.set(0, 2, a);
     191         [ +  - ]:         22 :   mat.set(2, 0, -a);
     192         [ +  - ]:         22 :   mat.set(2, 2, d);
     193                 :            : 
     194                 :            :   
     195                 :            :     // Perform Pre-Multiplication
     196 [ +  - ][ +  - ]:         22 :   *this = mat * *this;
                 [ +  - ]
     197         [ +  - ]:         22 :   mat.set_to_identity();
     198                 :            : 
     199         [ +  - ]:         22 :   if(d)
     200                 :            :   {
     201                 :            :       // Place values in appropriate places for rotate about x
     202         [ +  - ]:         22 :     mat.set(1, 1, c/d);
     203         [ +  - ]:         22 :     mat.set(1, 2, b/d);
     204         [ +  - ]:         22 :     mat.set(2, 1, -b/d);
     205         [ +  - ]:         22 :     mat.set(2, 2, c/d);
     206                 :            :   
     207                 :            :       // Perform Pre-Multiplication
     208 [ +  - ][ +  - ]:         22 :     *this = mat * *this;
                 [ +  - ]
     209         [ +  - ]:         22 :     mat.set_to_identity();
     210                 :            :   }
     211                 :            :     
     212         [ +  - ]:         22 :   return *this;
     213                 :            : 
     214                 :            : }
     215                 :            : 
     216                 :          0 : CubitTransformMatrix& CubitTransformMatrix::rotate(double degrees,
     217                 :            :                                      const CubitVector& axis_from,
     218                 :            :                                      const CubitVector& axis_to)
     219                 :            : {
     220                 :            :     // Translate so that axis_from is at origin
     221         [ #  # ]:          0 :   translate (-axis_from); 
     222                 :            :   
     223                 :            :     // Rotate about specified axis
     224         [ #  # ]:          0 :   rotate (degrees, axis_to - axis_from);
     225                 :            :   
     226                 :            :     // Translate back
     227                 :          0 :   translate (axis_from);
     228                 :            :   
     229                 :          0 :   return *this;
     230                 :            : }
     231                 :            : 
     232                 :         11 : CubitTransformMatrix& CubitTransformMatrix::scale_about_origin (const CubitVector& scale)
     233                 :            : {
     234                 :         11 :   return scale_about_origin(scale.x(), scale.y(), scale.z());
     235                 :            : }
     236                 :            : 
     237                 :         11 : CubitTransformMatrix& CubitTransformMatrix::scale_about_origin (double x, double y, double z)
     238                 :            : {
     239         [ +  - ]:         11 :   CubitTransformMatrix mat;
     240         [ +  - ]:         11 :   mat.set(0, 0, x);
     241         [ +  - ]:         11 :   mat.set(1, 1, y);
     242         [ +  - ]:         11 :   mat.set(2, 2, z);
     243                 :            :   
     244                 :            :     // Perform Pre-Multiplication
     245 [ +  - ][ +  - ]:         11 :   *this = mat * *this;
                 [ +  - ]
     246                 :            :   
     247         [ +  - ]:         11 :   return *this;
     248                 :            : }
     249                 :            : 
     250                 :          0 : CubitTransformMatrix& CubitTransformMatrix::scale_about_origin (double scale)
     251                 :            : {
     252                 :          0 :   return scale_about_origin(scale, scale, scale);
     253                 :            : }
     254                 :            : 
     255                 :          0 : CubitTransformMatrix& CubitTransformMatrix::inverse()
     256                 :            : {
     257         [ #  # ]:          0 :   CubitMatrix matrix = *this;
     258 [ #  # ][ #  # ]:          0 :   matrix = matrix.inverse();
         [ #  # ][ #  # ]
     259         [ #  # ]:          0 :   for( int ii = 0; ii < 4; ii++ )
     260                 :            :   {
     261         [ #  # ]:          0 :     for( int jj = 0; jj < 4; jj++ )
     262                 :            :     {
     263 [ #  # ][ #  # ]:          0 :       set( ii, jj, matrix.get(ii,jj) );
     264                 :            :     }
     265                 :            :   }
     266         [ #  # ]:          0 :   return *this;
     267                 :            : }
     268                 :            : 
     269                 :            : 
     270                 :            :   // Post-multiplication of a point (M*V)
     271                 :        154 : CubitVector CubitTransformMatrix::operator* (const CubitVector& point) const
     272                 :            : {
     273                 :            :     // Make a sub-matrix, multiply the point by it.
     274         [ +  - ]:        154 :   CubitVector vec = (this->sub_matrix(3, 3))*point;
     275                 :            :     // Handle the fourth column here
     276                 :        154 :   vec.x(vec.x() + get(0, 3));
     277                 :        154 :   vec.y(vec.y() + get(1, 3));
     278                 :        154 :   vec.z(vec.z() + get(2, 3));
     279                 :            :   
     280                 :        154 :   return vec;
     281                 :            : }
     282                 :            : 
     283                 :            : 
     284                 :            :   // point * matrix
     285                 :            : CUBIT_UTIL_EXPORT
     286                 :          0 : CubitVector operator* (const CubitVector& point,
     287                 :            :                        const CubitTransformMatrix& matrix)
     288                 :            : {
     289                 :            :     // Make a 1x4 matrix, multiply matrix by it.
     290         [ #  # ]:          0 :   CubitMatrix m1(1,4);
     291 [ #  # ][ #  # ]:          0 :   m1.set(0, 0, point.x());
     292 [ #  # ][ #  # ]:          0 :   m1.set(0, 1, point.y());
     293 [ #  # ][ #  # ]:          0 :   m1.set(0, 2, point.z());
     294         [ #  # ]:          0 :   m1.set(0, 3, 1);
     295                 :            :   
     296                 :            :     // Perform the multiplication
     297 [ #  # ][ #  # ]:          0 :   m1 = m1 * matrix;
         [ #  # ][ #  # ]
     298                 :            :     // The result is a 1x4
     299                 :            :   
     300                 :            :     // Put the results into a vector (dividing by w), and return
     301         [ #  # ]:          0 :   double w = m1.get(0,3);
     302 [ #  # ][ #  # ]:          0 :   return CubitVector(m1.get(0,0)/w, m1.get(0,1)/w, m1.get(0,2)/w);
         [ #  # ][ #  # ]
                 [ #  # ]
     303                 :            : }
     304                 :            : 
     305                 :        154 : CubitTransformMatrix CubitTransformMatrix::operator*(
     306                 :            :   const CubitTransformMatrix& matrix) const
     307                 :            : {
     308         [ +  - ]:        154 :   CubitTransformMatrix rv;
     309 [ +  - ][ +  - ]:        308 :   CubitMatrix temp(4);
     310 [ +  - ][ +  - ]:        154 :   temp = CubitMatrix::operator*(matrix);
         [ +  - ][ +  - ]
     311         [ +  + ]:        770 :   for (int i = 0; i < 4; i++)
     312         [ +  + ]:       3080 :     for (int j = 0; j < 4; j++)
     313 [ +  - ][ +  - ]:       2464 :       rv.set(i, j, temp.get(i,j));
     314                 :        308 :   return rv;
     315                 :            : }
     316                 :            : 
     317                 :          0 : CubitMatrix CubitTransformMatrix::operator*(const CubitMatrix& matrix) const
     318                 :            : {
     319                 :          0 :   return CubitMatrix::operator*(matrix);
     320                 :            : }
     321                 :            : 
     322                 :          0 : CubitTransformMatrix CubitTransformMatrix::operator*(double val) const
     323                 :            : {
     324                 :          0 :   CubitTransformMatrix rv;
     325         [ #  # ]:          0 :   for (int i = 0; i < 4; i++)
     326         [ #  # ]:          0 :     for (int j = 0; j < 4; j++)
     327 [ #  # ][ #  # ]:          0 :       rv.set(i, j, this->get(i,j)*val);
     328                 :          0 :   return rv;
     329                 :            : }
     330                 :            : 
     331                 :          0 : void CubitTransformMatrix::print_me() const
     332                 :            : {
     333         [ #  # ]:          0 :   PRINT_INFO("%8.4f  %8.4f  %8.4f  %8.4f\n",
     334         [ #  # ]:          0 :     get(0,0), get(0,1), get(0,2), get(0,3));
     335         [ #  # ]:          0 :   PRINT_INFO("%8.4f  %8.4f  %8.4f  %8.4f\n",
     336         [ #  # ]:          0 :     get(1,0), get(1,1), get(1,2), get(1,3));
     337         [ #  # ]:          0 :   PRINT_INFO("%8.4f  %8.4f  %8.4f  %8.4f\n",
     338         [ #  # ]:          0 :     get(2,0), get(2,1), get(2,2), get(2,3));
     339         [ #  # ]:          0 :   PRINT_INFO("%8.4f  %8.4f  %8.4f  %8.4f\n",
     340         [ #  # ]:          0 :     get(3,0), get(3,1), get(3,2), get(3,3));
     341                 :          0 : }
     342                 :            : 
     343                 :            : //! return the origin of this system
     344                 :          0 : CubitVector CubitTransformMatrix::origin() const
     345                 :            : {
     346                 :          0 :   return CubitVector(this->get(0,3), this->get(1,3), this->get(2,3));
     347                 :            : }
     348                 :            : 
     349                 :            : //! return the x-axis
     350                 :          0 : CubitVector CubitTransformMatrix::x_axis() const
     351                 :            : {
     352         [ #  # ]:          0 :   CubitMatrix tmp1(4,1);
     353         [ #  # ]:          0 :   tmp1.set(0,0,1);
     354         [ #  # ]:          0 :   tmp1.set(1,0,0);
     355         [ #  # ]:          0 :   tmp1.set(2,0,0);
     356         [ #  # ]:          0 :   tmp1.set(3,0,0);
     357 [ #  # ][ #  # ]:          0 :   CubitMatrix tmp2 = (*this) * tmp1;
     358 [ #  # ][ #  # ]:          0 :   return CubitVector(tmp2.get(0,0), tmp2.get(1,0), tmp2.get(2,0));
         [ #  # ][ #  # ]
                 [ #  # ]
     359                 :            : }
     360                 :            : 
     361                 :            : //! return the y-axis
     362                 :          0 : CubitVector CubitTransformMatrix::y_axis() const
     363                 :            : {
     364         [ #  # ]:          0 :   CubitMatrix tmp1(4,1);
     365         [ #  # ]:          0 :   tmp1.set(0,0,0);
     366         [ #  # ]:          0 :   tmp1.set(1,0,1);
     367         [ #  # ]:          0 :   tmp1.set(2,0,0);
     368         [ #  # ]:          0 :   tmp1.set(3,0,0);
     369 [ #  # ][ #  # ]:          0 :   CubitMatrix tmp2 = (*this) * tmp1;
     370 [ #  # ][ #  # ]:          0 :   return CubitVector(tmp2.get(0,0), tmp2.get(1,0), tmp2.get(2,0));
         [ #  # ][ #  # ]
                 [ #  # ]
     371                 :            : }
     372                 :            : 
     373                 :            : //! return the z-axis
     374                 :          0 : CubitVector CubitTransformMatrix::z_axis() const
     375                 :            : {
     376         [ #  # ]:          0 :   CubitMatrix tmp1(4,1);
     377         [ #  # ]:          0 :   tmp1.set(0,0,0);
     378         [ #  # ]:          0 :   tmp1.set(1,0,0);
     379         [ #  # ]:          0 :   tmp1.set(2,0,1);
     380         [ #  # ]:          0 :   tmp1.set(3,0,0);
     381 [ #  # ][ #  # ]:          0 :   CubitMatrix tmp2 = (*this) * tmp1;
     382 [ #  # ][ #  # ]:          0 :   return CubitVector(tmp2.get(0,0), tmp2.get(1,0), tmp2.get(2,0));
         [ #  # ][ #  # ]
                 [ #  # ]
     383                 :            : }
     384                 :            : 
     385                 :            : 
     386                 :          0 : CubitTransformMatrix CubitTransformMatrix::construct_matrix(const CubitVector& origin,
     387                 :            :                                              const CubitVector& x_axis,
     388                 :            :                                              const CubitVector& y_axis)
     389                 :            : {
     390         [ #  # ]:          0 :   CubitTransformMatrix mat;
     391 [ #  # ][ #  # ]:          0 :   double angle = x_axis.interior_angle(CubitVector(1,0,0));
     392 [ #  # ][ #  # ]:          0 :   CubitVector axis = angle == 180 ? CubitVector(0,1,0) : CubitVector(1,0,0) * x_axis;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     393         [ #  # ]:          0 :   mat.rotate(angle, axis);
     394 [ #  # ][ #  # ]:          0 :   CubitVector y = mat * CubitVector(0,1,0);
     395         [ #  # ]:          0 :   angle = y_axis.interior_angle(y);
     396 [ #  # ][ #  # ]:          0 :   axis = angle == 180 ? CubitVector(0,0,1) : y * y_axis;
         [ #  # ][ #  # ]
     397         [ #  # ]:          0 :   mat.rotate(angle, axis);
     398         [ #  # ]:          0 :   mat.translate(origin);
     399                 :          0 :   return mat;
     400                 :            : }
     401                 :            : 
     402                 :          0 : void CubitTransformMatrix::get_rotation_axis_and_angle(CubitVector &rotation_axis, double &angle)
     403                 :            : {
     404                 :          0 :     double cos_theta = (this->get(0,0) + this->get(1,1) + this->get(2,2) - 1) / 2;
     405                 :            : 
     406                 :          0 :     double x = 0;
     407                 :          0 :     double y = 0;
     408                 :          0 :     double z = 0; 
     409                 :            :     
     410         [ #  # ]:          0 :     if (fabs(cos_theta - 1) < .0001)
     411                 :            :     {
     412                 :            :         // theta is 1 or almost 1
     413                 :          0 :         angle = 0;
     414                 :          0 :         x = 0;
     415                 :          0 :         y = 0;
     416                 :          0 :         z = 1;
     417                 :            :     }
     418         [ #  # ]:          0 :     else if (fabs(cos_theta + 1) > .0001)
     419                 :            :     {
     420                 :            :         // theta is NOT -1 or almost -1
     421                 :          0 :         angle = acos(cos_theta);
     422                 :          0 :         angle =  (angle * 180.0) / CUBIT_PI; // convert to degrees
     423                 :          0 :         double sin_theta = sqrt(1 - cos_theta * cos_theta);
     424                 :          0 :         x = ( (this->get(2,1) - this->get(1,2)) / 2 ) / sin_theta;
     425                 :          0 :         y = ( (this->get(0,2) - this->get(2,0)) / 2 ) / sin_theta;
     426                 :          0 :         z = ( (this->get(1,0) - this->get(0,1)) / 2 ) / sin_theta;
     427                 :            :     }
     428                 :            :     else
     429                 :            :     {
     430                 :          0 :         angle = 180;
     431         [ #  # ]:          0 :         if (this->get(0,0) >= this->get(1,1))
     432                 :            :         {
     433                 :            : 
     434         [ #  # ]:          0 :             if (this->get(0,0) >= this->get(2,2)) 
     435                 :            :             {
     436                 :            :                 // 0,0 is maximal diagonal term
     437                 :          0 :                 x = sqrt(this->get(0,0) - this->get(1,1) - this->get(2,2) + 1) / 2;
     438                 :          0 :                 double half_inverse = 1 / (2 * x);
     439                 :          0 :                 y = half_inverse * this->get(0,1);
     440                 :          0 :                 z = half_inverse * this->get(0,2);
     441                 :            :             } 
     442                 :            :             else
     443                 :            :             {
     444                 :            :                 // 2,2 is maximal diagonal term
     445                 :          0 :                 z = sqrt(this->get(2,2) - this->get(0,0) - this->get(1,1) + 1) / 2;
     446                 :          0 :                 double half_inverse = 1 / (2 * z);
     447                 :          0 :                 x = half_inverse * this->get(0,2);
     448                 :          0 :                 y = half_inverse * this->get(1,2);
     449                 :            :             }
     450                 :            :         }
     451                 :            :         else
     452                 :            :         {
     453         [ #  # ]:          0 :             if (this->get(1,1) >= this->get(2,2))
     454                 :            :             {
     455                 :            :                 // 1,1 is maximal diagonal term
     456                 :          0 :                 y = sqrt(this->get(1,1) - this->get(0,0) - this->get(2,2) + 1) / 2;
     457                 :          0 :                 double half_inverse = 1 / (2 * y);
     458                 :          0 :                 x = half_inverse * this->get(0,1);
     459                 :          0 :                 z = half_inverse * this->get(1,2);
     460                 :            :             } 
     461                 :            :             else
     462                 :            :             {
     463                 :            :                 // 2,2 is maximal diagonal term
     464                 :          0 :                 z = sqrt(this->get(2,2) - this->get(0,0) - this->get(1,1) + 1) / 2;
     465                 :          0 :                 double half_inverse = 1 / (2 * z);
     466                 :          0 :                 x = half_inverse * this->get(0,2);
     467                 :          0 :                 y = half_inverse * this->get(1,2);
     468                 :            :             }
     469                 :            :         }
     470                 :            : 
     471                 :            :     }
     472                 :            : 
     473                 :          0 :     rotation_axis.x(x);
     474                 :          0 :     rotation_axis.y(y);
     475                 :          0 :     rotation_axis.z(z);
     476                 :          0 : }

Generated by: LCOV version 1.11