Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

guge_linear.cpp

Go to the documentation of this file.
00001 /* LIBGUL - Geometry Utility Library
00002  * Copyright (C) 1998-1999 Norbert Irmer
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 #include "stdafx.h"
00021 
00022 #include "gul_types.h"
00023 #include "gul_float.h"
00024 #include "gul_vector.h"
00025 #include "guge_normalize.h"
00026 
00027 
00028 namespace guge {
00029 
00030 using gul::Ptr;
00031 using gul::rtr;
00032 using gul::hpoint;
00033 using gul::point;
00034 using gul::point2;
00035 using gul::normalize;
00036 using gul::cross_product;
00037 using gul::abs_equal;
00038 using gul::rel_equal;
00039 using gul::zero_sine;
00040 using gul::euclid;
00041 
00042 /*--------------------------------------------------------------------------
00043   check, if a curve (given by its homogeneous control points), can be 
00044   approximated with a line through its endpoints
00045 ---------------------------------------------------------------------------*/
00046 template< class T, class HP, class EP >
00047 bool IsLinear( const int n, const Ptr< HP >& Pw, 
00048                const T tol )
00049 {
00050   EP A,B,b,u0,X;
00051   point<T> L,H,R;
00052   int i;
00053   bool bzero;
00054 
00055   A = euclid( Pw[0] );
00056   B = euclid( Pw[n] );
00057 
00058   b = B - A;
00059   bzero = rel_equal(B,A,rtr<T>::zero_tol());
00060   
00061   if( !bzero )
00062   {
00063     normalize( &u0, b );
00064     L = cross_product( u0, A );
00065 
00066     for( i = 1; i < n; i++ )
00067     {
00068       X = euclid( Pw[i] );
00069 
00070       H = cross_product( u0, X );
00071       R = H - L;
00072 
00073       if( !abs_equal( H, L, tol ) )
00074         return false;
00075     }
00076   }
00077   else
00078   {
00079     for( i = 0; i <= n; i++ )
00080     {
00081       X = euclid( Pw[i] );
00082       B = X - A;
00083 
00084       if( !abs_equal(X,A,tol) )
00085         return false;
00086     }
00087   }
00088   return true;
00089 }
00090 // template instantiation
00091 template bool IsLinear<float,hpoint<float>,point<float> >(
00092                         const int n, const Ptr< hpoint<float> >& Pw, 
00093                         const float tol );
00094 template bool IsLinear<double,hpoint<double>,point<double> >(
00095                         const int n, const Ptr< hpoint<double> >& Pw, 
00096                         const double tol );
00097 template bool IsLinear<float,point<float>,point<float> >(
00098                         const int n, const Ptr< point<float> >& Pw, 
00099                         const float tol );
00100 template bool IsLinear<double,point<double>,point<double> >(
00101                         const int n, const Ptr< point<double> >& Pw, 
00102                         const double tol );
00103 
00104 template bool IsLinear<float,hpoint2<float>,point2<float> >(
00105                         const int n, const Ptr< hpoint2<float> >& Pw, 
00106                         const float tol );
00107 template bool IsLinear<double,hpoint2<double>,point2<double> >(
00108                         const int n, const Ptr< hpoint2<double> >& Pw, 
00109                         const double tol );
00110 template bool IsLinear<float,point2<float>,point2<float> >(
00111                         const int n, const Ptr< point2<float> >& Pw, 
00112                         const float tol );
00113 template bool IsLinear<double,point2<double>,point2<double> >(
00114                         const int n, const Ptr< point2<double> >& Pw, 
00115                         const double tol );
00116 
00117 
00118 /*-------------------------------------------------------------------------
00119   check, if a surface can be approximated with two triangles through its
00120   four corners
00121 ---------------------------------------------------------------------------*/
00122 template< class T, class HP >
00123 bool IsPlanar( const int nu, const int nv, const Ptr< Ptr< HP > >& Pw,
00124                const T tol )
00125 {
00126   point<T> A,B,C,D,b,c,d,h,n0,u0,X,H,L,R;
00127   T r,l;
00128   bool is_point,is_plane, bzero,czero,dzero;
00129   int i,j;
00130   
00131   A = euclid( Pw[0][0] );
00132   B = euclid( Pw[nv][0] );
00133   C = euclid( Pw[nv][nu] );
00134   D = euclid( Pw[0][nu] );
00135 
00136   b = B - A;
00137   bzero = rel_equal( B, A, rtr<T>::zero_tol() );
00138   c = C - A;
00139   czero = rel_equal( C, A, rtr<T>::zero_tol() );
00140   d = D - A;
00141   dzero = rel_equal( D, A, rtr<T>::zero_tol() );      
00142 
00143   is_point = false;
00144   is_plane = false;
00145   
00146   if( bzero && czero && dzero )               /* Punkt */
00147     is_point = true;
00148   else                                                             /* Ebene */
00149   {
00150     if( (!bzero) && (!czero) )
00151     {
00152       h = cross_product( b, c );
00153       is_plane = !zero_sine( b, c, rtr<T>::zero_tol() );  /* b || c ??? */      
00154     }
00155        
00156     if( is_plane )
00157     {
00158       normalize( &n0, h );  
00159     }  
00160     else
00161     {  
00162       if( (!bzero) && (!dzero) )
00163       {
00164         h = cross_product( b, d );
00165         is_plane = !zero_sine( b, d, rtr<T>::zero_tol() );  /* b || d ??? */ 
00166       }               
00167 
00168       if( is_plane )
00169       {
00170         normalize( &n0, h );
00171       }
00172       else
00173       {
00174         if( (!czero) && (!dzero) )
00175         {
00176           h = cross_product( c, d );
00177           is_plane = !zero_sine( c, d, rtr<T>::zero_tol() );  /* c || d ??? */ 
00178         }               
00179 
00180         if( is_plane )
00181         {
00182           normalize( &n0, h );
00183         }
00184         else                                                     /* Gerade */ 
00185           if( !bzero )
00186             normalize( &u0, b );
00187           else
00188             if( !czero )
00189               normalize( &u0, c );
00190             else
00191               normalize( &u0, d );              
00192       }
00193     }            
00194   } 
00195 
00196   if( is_plane )
00197   {
00198     r = n0 * A;
00199     if( r < 0 )
00200     {
00201       r = -r;
00202       n0 = -n0;
00203     }  
00204     
00205     for( j = 0; j <= nv; j++ )
00206       for( i = 0; i <= nu; i++ )
00207       {
00208         X = euclid( Pw[j][i] );
00209 
00210         l = n0 * X;
00211         if( gul::rtr<T>::fabs( l - r ) > tol ) return false;
00212       }
00213   }                 
00214   else if( !is_point )
00215   {
00216     L = cross_product( u0, A );
00217 
00218     for( j = 0; j <= nv; j++ )
00219       for( i = 0; i <= nu; i++ )
00220       {
00221         X = euclid( Pw[j][i] );
00222 
00223         H = cross_product( u0, X );
00224         R = H - L;
00225 
00226         if( !abs_equal( H, L, tol ) )
00227           return false;
00228       }
00229   }
00230   else
00231   {
00232     for( j = 0; j <= nv; j++ )
00233       for( i = 0; i <= nu; i++ )
00234       {
00235         X = euclid( Pw[j][i] );
00236         R = X - A;
00237 
00238         if( !abs_equal( X, A, tol ) )
00239           return false;
00240       }
00241   }
00242   return true;
00243 }
00244 // template instantiation
00245 template bool IsPlanar( 
00246           const int nu, const int nv, const Ptr< Ptr< hpoint<float> > >& Pw,
00247           const float tol );
00248 template bool IsPlanar( 
00249           const int nu, const int nv, const Ptr< Ptr< hpoint<double> > >& Pw,
00250           const double tol );
00251 
00252 template bool IsPlanar( 
00253           const int nu, const int nv, const Ptr< Ptr< point<float> > >& Pw,
00254           const float tol );
00255 template bool IsPlanar( 
00256           const int nu, const int nv, const Ptr< Ptr< point<double> > >& Pw,
00257           const double tol );
00258 
00259 /*-------------------------------------------------------------------------
00260   check if a polyline forms a rectangle
00261 -------------------------------------------------------------------------*/
00262 
00263 template< class T >
00264 GULAPI bool isRectangle( int nP, const Ptr< point2<T> >& P,
00265                          T& u1, T& u2, T& v1, T& v2 )
00266 {
00267   if( nP != 5 ) return false;
00268 
00269   // last point must be the same as the first one 
00270   if( (P[0].x != P[4].x) || (P[0].y != P[4].y) )
00271     return false;
00272 
00273   if( P[0].y == P[1].y )
00274   {
00275     if( (P[2].y != P[3].y) || 
00276         (P[3].x != P[0].x) || (P[2].x != P[1].x) )
00277       return false;
00278 
00279     if( P[3].y < P[0].y )
00280     {
00281       v1 = P[3].y;
00282       v2 = P[0].y;
00283     }
00284     else
00285     {
00286       v1 = P[0].y;
00287       v2 = P[3].y;
00288     }
00289     if( P[2].x < P[0].x )
00290     {
00291       u1 = P[2].x;
00292       u2 = P[0].x;
00293     }
00294     else
00295     {
00296       u1 = P[0].x;
00297       u2 = P[2].x;
00298     }
00299   }
00300   else if( P[0].x == P[1].x )
00301   {
00302     if( (P[2].x != P[3].x) || 
00303         (P[3].y != P[0].y) || (P[2].y != P[1].y) )
00304       return false;
00305 
00306     if( P[3].x < P[0].x )
00307     {
00308       u1 = P[3].x;
00309       u2 = P[0].x;
00310     }
00311     else
00312     {
00313       u1 = P[0].x;
00314       u2 = P[3].x;
00315     }
00316     if( P[2].y < P[0].y )
00317     {
00318       u1 = P[2].x;
00319       u2 = P[0].x;
00320     }
00321     else
00322     {
00323       u1 = P[0].x;
00324       u2 = P[2].x;
00325     }
00326   }
00327   else
00328     return false;
00329 
00330   return true;
00331 }
00332 // template instantiation
00333 template GULAPI bool isRectangle( int nP, const Ptr< point2<float> >& P,
00334                   float& u1, float& u2, float& v1, float& v2 );
00335 template GULAPI bool isRectangle( int nP, const Ptr< point2<double> >& P,
00336                   double& u1, double& u2, double& v1, double& v2 );
00337 
00338 
00339 }
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 

Generated on Mon Jan 21 04:17:18 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001