LCOV - code coverage report
Current view: top level - src - HomXform.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 49 55 89.1 %
Date: 2020-12-16 07:07:30 Functions: 4 4 100.0 %
Branches: 114 236 48.3 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
       3                 :            :  * storing and accessing finite element mesh data.
       4                 :            :  *
       5                 :            :  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
       6                 :            :  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
       7                 :            :  * retains certain rights in this software.
       8                 :            :  *
       9                 :            :  * This library is free software; you can redistribute it and/or
      10                 :            :  * modify it under the terms of the GNU Lesser General Public
      11                 :            :  * License as published by the Free Software Foundation; either
      12                 :            :  * version 2.1 of the License, or (at your option) any later version.
      13                 :            :  *
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "moab/HomXform.hpp"
      17                 :            : #include <assert.h>
      18                 :            : 
      19                 :            : namespace moab
      20                 :            : {
      21                 :            : 
      22                 :         58 : HomCoord HomCoord::unitv[3] = { HomCoord( 1, 0, 0 ), HomCoord( 0, 1, 0 ), HomCoord( 0, 0, 1 ) };
      23                 :         58 : HomCoord HomCoord::IDENTITY( 1, 1, 1 );
      24                 :            : 
      25                 :        132 : HomCoord& HomCoord::getUnitv( int c )
      26                 :            : {
      27                 :        132 :     return unitv[c];
      28                 :            : }
      29                 :            : 
      30                 :            : int dum[] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
      31                 :         58 : HomXform HomXform::IDENTITY( dum );
      32                 :            : 
      33                 :         41 : void HomXform::three_pt_xform( const HomCoord& p1, const HomCoord& q1, const HomCoord& p2, const HomCoord& q2,
      34                 :            :                                const HomCoord& p3, const HomCoord& q3 )
      35                 :            : {
      36                 :            :     // pmin and pmax are min and max bounding box corners which are mapped to
      37                 :            :     // qmin and qmax, resp.  qmin and qmax are not necessarily min/max corners,
      38                 :            :     // since the mapping can change the orientation of the box in the q reference
      39                 :            :     // frame.  Re-interpreting the min/max bounding box corners does not change
      40                 :            :     // the mapping.
      41                 :            : 
      42                 :            :     // change that: base on three points for now (figure out whether we can
      43                 :            :     // just use two later); three points are assumed to define an orthogonal
      44                 :            :     // system such that (p2-p1)%(p3-p1) = 0
      45                 :            : 
      46                 :            :     // use the three point rule to compute the mapping, from Mortensen,
      47                 :            :     // "Geometric Modeling".  If p1, p2, p3 and q1, q2, q3 are three points in
      48                 :            :     // the two coordinate systems, the three pt rule is:
      49                 :            :     //
      50                 :            :     // v1 = p2 - p1
      51                 :            :     // v2 = p3 - p1
      52                 :            :     // v3 = v1 x v2
      53                 :            :     // w1-w3 similar, with q1-q3
      54                 :            :     // V = matrix with v1-v3 as rows
      55                 :            :     // W similar, with w1-w3
      56                 :            :     // R = V^-1 * W
      57                 :            :     // t = q1 - p1 * W
      58                 :            :     // Form transform matrix M from R, t
      59                 :            : 
      60                 :            :     // check to see whether unity transform applies
      61 [ +  - ][ +  + ]:         41 :     if( p1 == q1 && p2 == q2 && p3 == q3 )
         [ +  - ][ +  + ]
         [ +  - ][ +  - ]
                 [ +  + ]
      62                 :            :     {
      63         [ +  - ]:         22 :         *this = HomXform::IDENTITY;
      64                 :         41 :         return;
      65                 :            :     }
      66                 :            : 
      67                 :            :     // first, construct 3 pts from input
      68         [ +  - ]:         19 :     HomCoord v1 = p2 - p1;
      69 [ +  - ][ +  + ]:         19 :     assert( v1.i() != 0 || v1.j() != 0 || v1.k() != 0 );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
      70         [ +  - ]:         19 :     HomCoord v2 = p3 - p1;
      71         [ +  - ]:         19 :     HomCoord v3 = v1 * v2;
      72                 :            : 
      73 [ +  - ][ +  + ]:         19 :     if( v3.length_squared() == 0 )
      74                 :            :     {
      75                 :            :         // 1d coordinate system; set one of v2's coordinates such that
      76                 :            :         // it's orthogonal to v1
      77 [ +  - ][ +  + ]:          7 :         if( v1.i() == 0 )
      78         [ +  - ]:          1 :             v2.set( 1, 0, 0 );
      79 [ +  - ][ +  - ]:          6 :         else if( v1.j() == 0 )
      80         [ +  - ]:          6 :             v2.set( 0, 1, 0 );
      81 [ #  # ][ #  # ]:          0 :         else if( v1.k() == 0 )
      82         [ #  # ]:          0 :             v2.set( 0, 0, 1 );
      83                 :            :         else
      84                 :          0 :             assert( false );
      85 [ +  - ][ +  - ]:          7 :         v3 = v1 * v2;
      86 [ +  - ][ -  + ]:          7 :         assert( v3.length_squared() != 0 );
      87                 :            :     }
      88                 :            :     // assert to make sure they're each orthogonal
      89 [ +  - ][ +  - ]:         19 :     assert( v1 % v2 == 0 && v1 % v3 == 0 && v2 % v3 == 0 );
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
      90         [ +  - ]:         19 :     v1.normalize();
      91         [ +  - ]:         19 :     v2.normalize();
      92         [ +  - ]:         19 :     v3.normalize();
      93                 :            :     // Make sure h is set to zero here, since it'll mess up things if it's one
      94                 :         19 :     v1.homCoord[3] = v2.homCoord[3] = v3.homCoord[3] = 0;
      95                 :            : 
      96         [ +  - ]:         19 :     HomCoord w1 = q2 - q1;
      97 [ +  - ][ +  + ]:         19 :     assert( w1.i() != 0 || w1.j() != 0 || w1.k() != 0 );
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
      98         [ +  - ]:         19 :     HomCoord w2 = q3 - q1;
      99         [ +  - ]:         19 :     HomCoord w3 = w1 * w2;
     100                 :            : 
     101 [ +  - ][ +  + ]:         19 :     if( w3.length_squared() == 0 )
     102                 :            :     {
     103                 :            :         // 1d coordinate system; set one of w2's coordinates such that
     104                 :            :         // it's orthogonal to w1
     105 [ +  - ][ +  + ]:          7 :         if( w1.i() == 0 )
     106         [ +  - ]:          3 :             w2.set( 1, 0, 0 );
     107 [ +  - ][ +  - ]:          4 :         else if( w1.j() == 0 )
     108         [ +  - ]:          4 :             w2.set( 0, 1, 0 );
     109 [ #  # ][ #  # ]:          0 :         else if( w1.k() == 0 )
     110         [ #  # ]:          0 :             w2.set( 0, 0, 1 );
     111                 :            :         else
     112                 :          0 :             assert( false );
     113 [ +  - ][ +  - ]:          7 :         w3 = w1 * w2;
     114 [ +  - ][ -  + ]:          7 :         assert( w3.length_squared() != 0 );
     115                 :            :     }
     116                 :            :     // assert to make sure they're each orthogonal
     117 [ +  - ][ +  - ]:         19 :     assert( w1 % w2 == 0 && w1 % w3 == 0 && w2 % w3 == 0 );
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
     118         [ +  - ]:         19 :     w1.normalize();
     119         [ +  - ]:         19 :     w2.normalize();
     120         [ +  - ]:         19 :     w3.normalize();
     121                 :            :     // Make sure h is set to zero here, since it'll mess up things if it's one
     122                 :         19 :     w1.homCoord[3] = w2.homCoord[3] = w3.homCoord[3] = 0;
     123                 :            : 
     124                 :            :     // form v^-1 as transpose (ok for orthogonal vectors); put directly into
     125                 :            :     // transform matrix, since it's eventually going to become R
     126 [ +  - ][ +  - ]:         19 :     *this = HomXform( v1.i(), v2.i(), v3.i(), 0, v1.j(), v2.j(), v3.j(), 0, v1.k(), v2.k(), v3.k(), 0, 0, 0, 0, 1 );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     127                 :            : 
     128                 :            :     // multiply by w to get R
     129 [ +  - ][ +  - ]:         19 :     *this *= HomXform( w1.i(), w1.j(), w1.k(), 0, w2.i(), w2.j(), w2.k(), 0, w3.i(), w3.j(), w3.k(), 0, 0, 0, 0, 1 );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     130                 :            : 
     131                 :            :     // compute t and put into last row
     132 [ +  - ][ +  - ]:         19 :     HomCoord t              = q1 - p1 * *this;
     133         [ +  - ]:         19 :     ( *this ).XFORM( 3, 0 ) = t.i();
     134         [ +  - ]:         19 :     ( *this ).XFORM( 3, 1 ) = t.j();
     135         [ +  - ]:         19 :     ( *this ).XFORM( 3, 2 ) = t.k();
     136                 :            : 
     137                 :            :     // M should transform p to q
     138 [ +  - ][ +  - ]:         19 :     assert( ( q1 == p1 * *this ) && ( q2 == p2 * *this ) && ( q3 == p3 * *this ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ +  - ]
         [ +  - ][ +  - ]
           [ #  #  #  #  
                   #  # ]
     139                 :            : }
     140                 :            : 
     141 [ +  - ][ +  - ]:        232 : }  // namespace moab

Generated by: LCOV version 1.11