BWAPI
|
00001 // Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Nef_S2/include/CGAL/Nef_S2/Normalizing.h $ 00015 // $Id: Normalizing.h 43821 2008-06-27 10:04:22Z hachenb $ 00016 // 00017 // 00018 // Author(s) : Peter Hachenberger <hachenberger@mpi-sb.mpg.de> 00019 #ifndef CGAL_NORMALIZING_H 00020 #define CGAL_NORMALIZING_H 00021 00022 #include <CGAL/Nef_S2/Sphere_point.h> 00023 #include <CGAL/Nef_S2/Sphere_circle.h> 00024 #include <CGAL/Nef_S2/Sphere_direction.h> 00025 #include <CGAL/Fraction_traits.h> 00026 00027 #undef CGAL_NEF_DEBUG 00028 #define CGAL_NEF_DEBUG 307 00029 #include <CGAL/Nef_2/debug.h> 00030 00031 #ifdef CCGAL_USE_LEDA 00032 #include <CGAL/Cartesian.h> 00033 #include <CGAL/leda_rational.h> 00034 #endif 00035 00036 CGAL_BEGIN_NAMESPACE 00037 00038 class Homogeneous_tag; 00039 class Cartesian_tag; 00040 template<typename Tag> class Normalizing; 00041 00042 template<> 00043 class Normalizing<Homogeneous_tag> { 00044 public: 00045 00046 template <typename iterator> static 00047 void normalized(iterator begin, iterator end) { 00048 typedef typename std::iterator_traits<iterator>::value_type RT; 00049 00050 iterator i = begin; 00051 while(i!=end && *i == RT(0)) ++i; 00052 if(i==end) 00053 return; 00054 00055 RT g = *i; 00056 for(iterator j=i+1; j!=end; ++j) 00057 g = (*j == 0 ? g : CGAL_NTS gcd(g,*j)); 00058 g=CGAL_NTS abs(g); 00059 00060 for(; i!=end; ++i) 00061 *i = CGAL::integral_division(*i,g); 00062 } 00063 00064 template <typename R> static 00065 CGAL::Point_3<R> normalized(const CGAL::Point_3<R>& p) { 00066 00067 typedef typename R::RT RT; 00068 00069 RT g = p.hw(); 00070 g = (p.hx() == 0 ? g : CGAL_NTS gcd(g,p.hx())); 00071 g = (p.hy() == 0 ? g : CGAL_NTS gcd(g,p.hy())); 00072 g = (p.hz() == 0 ? g : CGAL_NTS gcd(g,p.hz())); 00073 00074 RT x = p.hx()/g; 00075 RT y = p.hy()/g; 00076 RT z = p.hz()/g; 00077 RT w = p.hw()/g; 00078 00079 return typename R::Point_3(x,y,z,w); 00080 } 00081 00082 template <typename R> static 00083 CGAL::Sphere_point<R> normalized(const CGAL::Sphere_point<R>& p) { 00084 00085 typedef typename R::RT RT; 00086 00087 RT g = (p.x()==0) ? ((p.y()==0) ? ((p.z()==0) ? 1: p.z()): p.y()): p.x(); 00088 00089 if(p.y() != 0) g = CGAL_NTS gcd(g,p.y()); 00090 if(p.z() != 0) g = CGAL_NTS gcd(g,p.z()); 00091 00092 if(g<0) g = -g; 00093 00094 RT x = p.x()/g; 00095 RT y = p.y()/g; 00096 RT z = p.z()/g; 00097 00098 return CGAL::Sphere_point<R>(x,y,z); 00099 } 00100 00101 template <typename R> static 00102 CGAL::Vector_3<R> normalized(const CGAL::Vector_3<R>& p) { 00103 00104 typedef typename R::RT RT; 00105 00106 RT g = (p.hx()==0) ? ((p.hy()==0) ? ((p.hz()==0) ? 1: p.hz()): p.hy()): p.hx(); 00107 00108 if(p.hy() != 0) g = CGAL_NTS gcd(g,p.hy()); 00109 if(p.hz() != 0) g = CGAL_NTS gcd(g,p.hz()); 00110 00111 if(g<0) g = -g; 00112 00113 RT x = p.hx()/g; 00114 RT y = p.hy()/g; 00115 RT z = p.hz()/g; 00116 00117 return typename R::Vector_3(x,y,z); 00118 } 00119 00120 template <typename R> static 00121 CGAL::Sphere_direction<R> normalized(const CGAL::Sphere_direction<R>& c) { 00122 00123 typename R::Plane_3 h = c.plane(); 00124 CGAL_assertion(!(h.a()==0 && h.b()==0 && h.c()==0 && h.d()==0)); 00125 00126 typedef typename R::RT RT; 00127 00128 RT x = (h.a()==0) ? ((h.b()==0) ? ((h.c()==0) ? ((h.d()==0) ? 1 00129 : h.d()) 00130 : h.c()) 00131 : h.b()) 00132 : h.a(); 00133 00134 if(h.b() != 0) 00135 x = gcd(x,h.b()); 00136 if(h.c() != 0) 00137 x = gcd(x,h.c()); 00138 if(h.d() !=0) 00139 x = gcd(x,h.d()); 00140 00141 x = CGAL_NTS abs(x); 00142 00143 RT pa = h.a()/x; 00144 RT pb = h.b()/x; 00145 RT pc = h.c()/x; 00146 RT pd = h.d()/x; 00147 00148 return CGAL::Sphere_direction<R>(typename R::Plane_3(pa,pb,pc,pd)); 00149 } 00150 00151 template <typename R> static 00152 CGAL::Plane_3<R> normalized(const CGAL::Plane_3<R>& h) { 00153 00154 CGAL_assertion(!(h.a()==0 && h.b()==0 && h.c()==0 && h.d()==0)); 00155 00156 typedef typename R::RT RT; 00157 00158 RT x = (h.a()==0) ? ((h.b()==0) ? ((h.c()==0) ? ((h.d()==0) ? 1 00159 : h.d()) 00160 : h.c()) 00161 : h.b()) 00162 : h.a(); 00163 00164 CGAL_NEF_TRACE("gcd... i"<<' '); 00165 00166 if(h.b() != 0) 00167 x = CGAL_NTS gcd(x,h.b()); 00168 CGAL_NEF_TRACE(x<<' '); 00169 if(h.c() != 0) 00170 x = CGAL_NTS gcd(x,h.c()); 00171 CGAL_NEF_TRACE(x<<' '); 00172 if(h.d() !=0) 00173 x = CGAL_NTS gcd(x,h.d()); 00174 CGAL_NEF_TRACEN(x); 00175 00176 x = CGAL_NTS abs(x); 00177 00178 RT pa = h.a()/x; 00179 RT pb = h.b()/x; 00180 RT pc = h.c()/x; 00181 RT pd = h.d()/x; 00182 00183 CGAL_NEF_TRACEN(" after normalizing " << typename R::Plane_3(pa,pb,pc,pd)); 00184 return typename R::Plane_3(pa,pb,pc,pd); 00185 } 00186 00187 template <typename R> static 00188 CGAL::Sphere_circle<R> normalized(const CGAL::Sphere_circle<R>& c) { 00189 00190 typename R::Plane_3 h = c.plane(); 00191 CGAL_assertion(!(h.a()==0 && h.b()==0 && h.c()==0 && h.d()==0)); 00192 00193 typedef typename R::RT RT; 00194 00195 RT x = (h.a()==0) ? ((h.b()==0) ? ((h.c()==0) ? ((h.d()==0) ? 1 00196 : h.d()) 00197 : h.c()) 00198 : h.b()) 00199 : h.a(); 00200 00201 if(h.b() != 0) 00202 x = CGAL_NTS gcd(x,h.b()); 00203 if(h.c() != 0) 00204 x = CGAL_NTS gcd(x,h.c()); 00205 if(h.d() !=0) 00206 x = CGAL_NTS gcd(x,h.d()); 00207 00208 x = CGAL_NTS abs(x); 00209 00210 RT pa = h.a()/x; 00211 RT pb = h.b()/x; 00212 RT pc = h.c()/x; 00213 RT pd = h.d()/x; 00214 00215 return CGAL::Sphere_circle<R>(typename R::Plane_3(pa,pb,pc,pd)); 00216 } 00217 }; 00218 00219 template<> 00220 class Normalizing<Cartesian_tag> { 00221 public: 00222 template <typename R> static 00223 CGAL::Point_3<R> normalized(const CGAL::Point_3<R>& p) { 00224 return p; 00225 } 00226 00227 template <typename R> static 00228 CGAL::Vector_3<R> normalized(const CGAL::Vector_3<R>& p) { 00229 return p; 00230 } 00231 00232 template <typename R> static 00233 CGAL::Sphere_point<R> normalized(const CGAL::Sphere_point<R>& p) { 00234 00235 typedef typename R::RT RT; 00236 00237 RT g = (p.hx() != 0 ? p.hx() : (p.hy() != 0 ? p.hy() : p.hz())); 00238 g = CGAL_NTS abs(g); 00239 00240 RT x = p.hx()/g; 00241 RT y = p.hy()/g; 00242 RT z = p.hz()/g; 00243 00244 return CGAL::Sphere_point<R>(x,y,z); 00245 } 00246 00247 template <typename R> static 00248 CGAL::Sphere_direction<R> normalized(const CGAL::Sphere_direction<R>& c) { 00249 return c; 00250 } 00251 00252 #ifdef CCGAL_USE_LEDA 00253 // specialization: Plane_3 < Cartesian < leda_rational > > 00254 00255 00256 static Plane_3<CGAL::Cartesian<leda_rational> > 00257 normalized(Plane_3<CGAL::Cartesian<leda_rational> >& h) { 00258 00259 CGAL_assertion(!(h.a()==0 && h.b()==0 && h.c()==0 && h.d()==0)); 00260 00261 typedef leda_rational FT; 00262 00263 FT x = (h.a()==0) ? ((h.b()==0) ? ((h.c()==0) ? ((h.d()==0) ? 1 00264 : h.d()) 00265 : h.c()) 00266 : h.b()) 00267 : h.a(); 00268 x = CGAL_NTS abs(x); 00269 00270 FT pa = h.a()/x; 00271 FT pb = h.b()/x; 00272 FT pc = h.c()/x; 00273 FT pd = h.d()/x; 00274 00275 pa.normalize(); 00276 pb.normalize(); 00277 pc.normalize(); 00278 pd.normalize(); 00279 00280 CGAL_NEF_TRACEN(" after normalizing " << CGAL::Plane_3<CGAL::Cartesian<leda_rational> >(pa,pb,pc,pd)); 00281 return CGAL::Plane_3<CGAL::Cartesian<leda_rational> >(pa,pb,pc,pd); 00282 } 00283 00284 #endif 00285 00286 template <typename R> static 00287 CGAL::Plane_3<R> normalized(const CGAL::Plane_3<R>& h) { 00288 CGAL_assertion(!(h.a()==0 && h.b()==0 && h.c()==0 && h.d()==0)); 00289 00290 typedef typename R::FT FT; 00291 typedef Fraction_traits<FT> FracTraits; 00292 typedef std::vector<typename FracTraits::Numerator_type> NV; 00293 typedef typename NV::iterator NV_iter; 00294 00295 typename FracTraits::Numerator_type num; 00296 typename FracTraits::Denominator_type denom; 00297 typename FracTraits::Decompose decomposer; 00298 typename FracTraits::Compose composer; 00299 NV vec; 00300 00301 decomposer(h.a(),num,denom); 00302 vec.push_back(num); 00303 vec.push_back(denom); 00304 vec.push_back(denom); 00305 vec.push_back(denom); 00306 decomposer(h.b(),num,denom); 00307 vec[0]*=denom; 00308 vec[1]*=num; 00309 vec[2]*=denom; 00310 vec[3]*=denom; 00311 decomposer(h.c(),num,denom); 00312 vec[0]*=denom; 00313 vec[1]*=denom; 00314 vec[2]*=num; 00315 vec[3]*=denom; 00316 decomposer(h.d(),num,denom); 00317 vec[0]*=denom; 00318 vec[1]*=denom; 00319 vec[2]*=denom; 00320 vec[3]*=num; 00321 00322 Normalizing<Homogeneous_tag>:: 00323 normalized(vec.begin(),vec.end()); 00324 return typename R::Plane_3(composer(vec[0],1), 00325 composer(vec[1],1), 00326 composer(vec[2],1), 00327 composer(vec[3],1)); 00328 } 00329 00330 template <typename R> static 00331 CGAL::Sphere_circle<R> normalized(CGAL::Sphere_circle<R>& c) { 00332 return c; 00333 } 00334 }; 00335 00336 /* 00337 template <typename R, typename iterator> 00338 void normalized(iterator begin, iterator end) { 00339 Normalizing<typename R::Kernel_tag>::normalized(begin, end); 00340 } 00341 */ 00342 00343 template <typename R> 00344 CGAL::Point_3<R> normalized(const CGAL::Point_3<R>& p) { 00345 return Normalizing<typename R::Kernel_tag>::normalized(p); 00346 } 00347 00348 template <typename R> 00349 CGAL::Sphere_point<R> normalized(const CGAL::Sphere_point<R>& p) { 00350 return Normalizing<typename R::Kernel_tag>::normalized(p); 00351 } 00352 00353 template <typename R> 00354 CGAL::Vector_3<R> normalized(const CGAL::Vector_3<R>& p) { 00355 return Normalizing<typename R::Kernel_tag>::normalized(p); 00356 } 00357 00358 template <typename R> 00359 CGAL::Sphere_direction<R> normalized(const CGAL::Sphere_direction<R>& c) { 00360 return Normalizing<typename R::Kernel_tag>::normalized(c); 00361 } 00362 00363 template <typename R> 00364 CGAL::Plane_3<R> normalized(const CGAL::Plane_3<R>& h) { 00365 return Normalizing<typename R::Kernel_tag>::normalized(h); 00366 } 00367 00368 template <typename R> 00369 CGAL::Sphere_circle<R> normalized(const CGAL::Sphere_circle<R>& c) { 00370 return Normalizing<typename R::Kernel_tag>::normalized(c); 00371 } 00372 00373 CGAL_END_NAMESPACE 00374 #endif // CGAL_NORMALIZING_H