00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00044
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
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
00120
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 )
00147 is_point = true;
00148 else
00149 {
00150 if( (!bzero) && (!czero) )
00151 {
00152 h = cross_product( b, c );
00153 is_plane = !zero_sine( b, c, rtr<T>::zero_tol() );
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() );
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() );
00178 }
00179
00180 if( is_plane )
00181 {
00182 normalize( &n0, h );
00183 }
00184 else
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
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
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
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
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