LCOV - code coverage report
Current view: top level - src/mesquite/Misc - MsqGeomPrim.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 0 116 0.0 %
Date: 2020-07-18 00:09:26 Functions: 0 16 0.0 %
Branches: 0 314 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* *****************************************************************
       2                 :            :     MESQUITE -- The Mesh Quality Improvement Toolkit
       3                 :            : 
       4                 :            :     Copyright 2007 Sandia National Laboratories.  Developed at the
       5                 :            :     University of Wisconsin--Madison under SNL contract number
       6                 :            :     624796.  The U.S. Government and the University of Wisconsin
       7                 :            :     retain certain rights to 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                 :            :     This library is distributed in the hope that it will be useful,
      15                 :            :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :            :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17                 :            :     Lesser General Public License for more details.
      18                 :            : 
      19                 :            :     You should have received a copy of the GNU Lesser General Public License
      20                 :            :     (lgpl.txt) along with this library; if not, write to the Free Software
      21                 :            :     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      22                 :            : 
      23                 :            :     (2007) [email protected]
      24                 :            : 
      25                 :            :   ***************************************************************** */
      26                 :            : 
      27                 :            : /** \file MsqGeomPrim.cpp
      28                 :            :  *  \brief
      29                 :            :  *  \author Jason Kraftcheck
      30                 :            :  */
      31                 :            : 
      32                 :            : #include "Mesquite.hpp"
      33                 :            : #include "MsqGeomPrim.hpp"
      34                 :            : 
      35                 :            : namespace MBMesquite
      36                 :            : {
      37                 :            : 
      38                 :          0 : bool MsqLine::intersect( const MsqLine& other, double& param, double epsilon ) const
      39                 :            : {
      40 [ #  # ][ #  # ]:          0 :     if( !closest( other, param ) ) return false;
      41         [ #  # ]:          0 :     Vector3D p1 = point( param );
      42 [ #  # ][ #  # ]:          0 :     Vector3D p2 = other.point( other.closest( p1 ) );
      43 [ #  # ][ #  # ]:          0 :     return ( p1 - p2 ).length_squared() < epsilon * epsilon;
      44                 :            : }
      45                 :            : 
      46                 :          0 : bool MsqLine::closest( const MsqLine& other, double& param ) const
      47                 :            : {
      48 [ #  # ][ #  # ]:          0 :     const Vector3D N = other.direction() * ( direction() * other.direction() );
         [ #  # ][ #  # ]
                 [ #  # ]
      49 [ #  # ][ #  # ]:          0 :     const double D   = -( N % other.point() );
      50 [ #  # ][ #  # ]:          0 :     const double dot = N % direction();
      51         [ #  # ]:          0 :     if( dot < DBL_EPSILON ) return false;  // parallel
      52 [ #  # ][ #  # ]:          0 :     param = -( N % point() + D ) / dot;
      53                 :          0 :     return true;
      54                 :            : }
      55                 :            : 
      56                 :          0 : bool MsqCircle::three_point( const Vector3D& p1, const Vector3D& p2, const Vector3D& p3, MsqCircle& result )
      57                 :            : {
      58 [ #  # ][ #  # ]:          0 :     Vector3D norm = ( p1 - p2 ) * ( p3 - p2 );
                 [ #  # ]
      59 [ #  # ][ #  # ]:          0 :     if( norm.length_squared() < DBL_EPSILON ) return false;
      60                 :            : 
      61 [ #  # ][ #  # ]:          0 :     MsqLine line1( 0.5 * ( p1 + p2 ), norm * ( p1 - p2 ) );
         [ #  # ][ #  # ]
                 [ #  # ]
      62 [ #  # ][ #  # ]:          0 :     MsqLine line2( 0.5 * ( p2 + p3 ), norm * ( p3 - p2 ) );
         [ #  # ][ #  # ]
                 [ #  # ]
      63                 :            :     double t_xsect;
      64 [ #  # ][ #  # ]:          0 :     if( !line1.closest( line2, t_xsect ) ) return false;
      65                 :            : 
      66         [ #  # ]:          0 :     Vector3D center = line1.point( t_xsect );
      67 [ #  # ][ #  # ]:          0 :     double radius   = ( ( center - p1 ).length() + ( center - p2 ).length() + ( center - p3 ).length() ) / 3.0;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      68 [ #  # ][ #  # ]:          0 :     result          = MsqCircle( center, norm, radius );
      69                 :          0 :     return true;
      70                 :            : }
      71                 :            : 
      72                 :          0 : bool MsqCircle::two_point( const Vector3D& center, const Vector3D& p1, const Vector3D& p2, MsqCircle& result )
      73                 :            : {
      74 [ #  # ][ #  # ]:          0 :     Vector3D norm = ( p1 - center ) * ( p2 - center );
                 [ #  # ]
      75 [ #  # ][ #  # ]:          0 :     if( norm.length_squared() < DBL_EPSILON ) return false;
      76                 :            : 
      77 [ #  # ][ #  # ]:          0 :     double radius = 0.5 * ( ( center - p1 ).length() + ( center - p2 ).length() );
         [ #  # ][ #  # ]
      78 [ #  # ][ #  # ]:          0 :     result        = MsqCircle( center, norm, radius );
      79                 :          0 :     return true;
      80                 :            : }
      81                 :            : 
      82                 :          0 : Vector3D MsqCircle::radial_vector() const
      83                 :            : {
      84                 :          0 :     int min_idx = 0;
      85         [ #  # ]:          0 :     if( normal()[1] < normal()[min_idx] ) min_idx = 1;
      86         [ #  # ]:          0 :     if( normal()[2] < normal()[min_idx] ) min_idx = 2;
      87                 :          0 :     Vector3D vect( 0, 0, 0 );
      88                 :          0 :     vect[min_idx] = 1;
      89         [ #  # ]:          0 :     vect          = normal() * vect;
      90                 :          0 :     vect *= radius() / vect.length();
      91                 :          0 :     return vect;
      92                 :            : }
      93                 :            : 
      94                 :          0 : Vector3D MsqCircle::closest( const Vector3D& point ) const
      95                 :            : {
      96 [ #  # ][ #  # ]:          0 :     const Vector3D from_center = point - center();
      97 [ #  # ][ #  # ]:          0 :     const Vector3D norm_proj   = normal() * ( normal() % from_center );  // unit normal!
         [ #  # ][ #  # ]
      98         [ #  # ]:          0 :     const Vector3D in_plane    = from_center - norm_proj;
      99         [ #  # ]:          0 :     const double length        = in_plane.length();
     100         [ #  # ]:          0 :     if( length < DBL_EPSILON )
     101 [ #  # ][ #  # ]:          0 :         return center() + radial_vector();
                 [ #  # ]
     102                 :            :     else
     103 [ #  # ][ #  # ]:          0 :         return center() + in_plane * radius() / length;
         [ #  # ][ #  # ]
                 [ #  # ]
     104                 :            : }
     105                 :            : 
     106                 :          0 : bool MsqCircle::closest( const Vector3D& point, Vector3D& result_pt, Vector3D& result_tngt ) const
     107                 :            : {
     108 [ #  # ][ #  # ]:          0 :     const Vector3D from_center = point - center();
     109 [ #  # ][ #  # ]:          0 :     Vector3D in_plane          = from_center - ( from_center % normal() );
         [ #  # ][ #  # ]
     110 [ #  # ][ #  # ]:          0 :     if( in_plane.length_squared() < DBL_EPSILON ) return false;
     111                 :            : 
     112 [ #  # ][ #  # ]:          0 :     result_pt   = center() + in_plane * radius() / in_plane.length();
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     113 [ #  # ][ #  # ]:          0 :     result_tngt = in_plane * normal();
                 [ #  # ]
     114                 :          0 :     return true;
     115                 :            : }
     116                 :            : 
     117                 :          0 : MsqPlane::MsqPlane( const Vector3D& p_normal, double coeff )
     118                 :            : {
     119                 :          0 :     const double len = p_normal.length();
     120         [ #  # ]:          0 :     mNormal          = p_normal / len;
     121                 :          0 :     mCoeff           = coeff / len;
     122                 :          0 : }
     123                 :            : 
     124                 :          0 : MsqPlane::MsqPlane( const Vector3D& p_normal, const Vector3D& p_point )
     125                 :          0 :     : mNormal( p_normal / p_normal.length() ), mCoeff( -( mNormal % p_point ) )
     126                 :            : {
     127                 :          0 : }
     128                 :            : 
     129                 :          0 : MsqPlane::MsqPlane( double a, double b, double c, double d ) : mNormal( a, b, c ), mCoeff( d )
     130                 :            : {
     131                 :          0 :     const double len = mNormal.length();
     132                 :          0 :     mNormal /= len;
     133                 :          0 :     mCoeff /= len;
     134                 :          0 : }
     135                 :            : 
     136                 :          0 : bool MsqPlane::intersect( const MsqPlane& plane, MsqLine& result ) const
     137                 :            : {
     138                 :          0 :     const double dot = normal() % plane.normal();
     139                 :          0 :     const double det = dot * dot - 1.0;
     140         [ #  # ]:          0 :     if( fabs( det ) < DBL_EPSILON )  // parallel
     141                 :          0 :         return false;
     142                 :            : 
     143                 :          0 :     const double s1 = ( coefficient() - dot * plane.coefficient() ) / det;
     144                 :          0 :     const double s2 = ( plane.coefficient() - dot * coefficient() ) / det;
     145 [ #  # ][ #  # ]:          0 :     result          = MsqLine( s1 * normal() + s2 * plane.normal(), normal() * plane.normal() );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     146                 :          0 :     return true;
     147                 :            : }
     148                 :            : 
     149                 :          0 : bool MsqPlane::intersect( const MsqLine& line, double& result ) const
     150                 :            : {
     151                 :          0 :     const double dot = line.direction() % normal();
     152         [ #  # ]:          0 :     if( fabs( dot ) < DBL_EPSILON ) return false;
     153                 :            : 
     154                 :          0 :     result = -( normal() % line.point() + coefficient() ) / dot;
     155                 :          0 :     return true;
     156                 :            : }
     157                 :            : 
     158                 :          0 : Vector3D MsqSphere::closest( const Vector3D& point ) const
     159                 :            : {
     160 [ #  # ][ #  # ]:          0 :     Vector3D diff = point - center();
     161         [ #  # ]:          0 :     double len    = diff.length();
     162         [ #  # ]:          0 :     if( len < DBL_EPSILON )
     163                 :            :     {
     164                 :            :         // pick any point
     165 [ #  # ][ #  # ]:          0 :         diff = Vector3D( 1, 0, 0 );
     166                 :          0 :         len  = 1;
     167                 :            :     }
     168                 :            : 
     169 [ #  # ][ #  # ]:          0 :     return center() + diff * radius() / len;
         [ #  # ][ #  # ]
                 [ #  # ]
     170                 :            : }
     171                 :            : 
     172                 :          0 : bool MsqSphere::closest( const Vector3D& point, Vector3D& point_on_sphere, Vector3D& normal_at_point ) const
     173                 :            : {
     174         [ #  # ]:          0 :     normal_at_point = point - center();
     175                 :          0 :     double len      = normal_at_point.length();
     176         [ #  # ]:          0 :     if( len < DBL_EPSILON ) return false;
     177                 :            : 
     178                 :          0 :     normal_at_point /= len;
     179 [ #  # ][ #  # ]:          0 :     point_on_sphere = center() + radius() * normal_at_point;
                 [ #  # ]
     180                 :          0 :     return true;
     181                 :            : }
     182                 :            : 
     183                 :          0 : bool MsqSphere::intersect( const MsqPlane& plane, MsqCircle& result ) const
     184                 :            : {
     185 [ #  # ][ #  # ]:          0 :     const Vector3D plane_pt  = plane.closest( center() );
     186 [ #  # ][ #  # ]:          0 :     const Vector3D plane_dir = plane_pt - center();
     187         [ #  # ]:          0 :     const double dir_sqr     = plane_dir.length_squared();
     188         [ #  # ]:          0 :     if( dir_sqr < DBL_EPSILON )
     189                 :            :     {  // plane passes through center of sphere
     190 [ #  # ][ #  # ]:          0 :         result = MsqCircle( center(), plane.normal(), radius() );
         [ #  # ][ #  # ]
                 [ #  # ]
     191                 :          0 :         return true;
     192                 :            :     }
     193                 :            : 
     194 [ #  # ][ #  # ]:          0 :     double rad_sqr = radius() * radius() - plane_dir.length_squared();
                 [ #  # ]
     195         [ #  # ]:          0 :     if( rad_sqr < 0 )  // no intersection
     196                 :          0 :         return false;
     197                 :            : 
     198 [ #  # ][ #  # ]:          0 :     result = MsqCircle( plane_pt, plane_dir, sqrt( rad_sqr ) );
     199                 :          0 :     return true;
     200                 :            : }
     201                 :            : 
     202                 :          0 : bool MsqSphere::intersect( const MsqSphere& sphere, MsqCircle& result ) const
     203                 :            : {
     204 [ #  # ][ #  # ]:          0 :     const Vector3D d  = sphere.center() - center();
                 [ #  # ]
     205         [ #  # ]:          0 :     const double dist = d.length();
     206 [ #  # ][ #  # ]:          0 :     if( dist > ( radius() + sphere.radius() ) ) return false;
                 [ #  # ]
     207                 :            : 
     208 [ #  # ][ #  # ]:          0 :     const double r1_sqr = radius() * radius();
     209 [ #  # ][ #  # ]:          0 :     const double r2_sqr = sphere.radius() * sphere.radius();
     210         [ #  # ]:          0 :     const double f      = ( d % d + r1_sqr - r2_sqr ) / 2;
     211                 :            :     // const double d1 = f / dist;
     212                 :            : 
     213         [ #  # ]:          0 :     const double rad = sqrt( r1_sqr - f * f / ( d % d ) );
     214 [ #  # ][ #  # ]:          0 :     Vector3D c       = center() + d * f / ( d % d );
         [ #  # ][ #  # ]
                 [ #  # ]
     215 [ #  # ][ #  # ]:          0 :     result           = MsqCircle( c, d, rad );
     216                 :          0 :     return true;
     217                 :            : }
     218                 :            : 
     219                 :            : }  // namespace MBMesquite

Generated by: LCOV version 1.11