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

boundingbox.h

Go to the documentation of this file.
00001 
00012 #ifndef __BOUNDINGBOX_H__
00013 #define __BOUNDINGBOX_H__
00014 
00015 #include <iostream>
00016 #include "aarectangle.h"
00017 #include "genericalgs.h"
00018 
00019 
00020 namespace Boundary {
00021 
00022   
00028 template<class T=double, class Boolean=bool, class Float=double>
00029 class BoundingBox {
00031   typedef BoundingBox<T,Boolean,Float> self;
00032   typedef BoundingBox<T,Boolean,Float> base;
00033 
00034 public:
00035   typedef AARectangle<T,Boolean,Float> Rectangle;
00036   typedef T value_type;
00037   
00039   virtual Boolean inside(T x, T y) const =0;
00040 
00042   virtual base& scale(T xscale, T yscale) =0;
00043 
00045   virtual base& rotate(Float angle) =0;
00046 
00048   virtual base& translate(T xoffset, T yoffset) =0;
00049 
00052   virtual Rectangle aarectangle() const =0;
00053   
00055   virtual base* clone() const=0;
00056 
00062   virtual std::ostream& put(std::ostream &s) const {  return s;  };
00063 };
00064 
00065 
00066 
00068 template<class T,class Boolean,class Float>
00069 std::ostream& operator<<(std::ostream &s, const BoundingBox<T,Boolean,Float>& b) {  return b.put(s);  }
00070 
00071 
00072 
00079 template<class T=int,class Boolean=bool,class Float=double,
00080          class BoxType=AAArbitraryRectangle<T,Boolean,Float> >
00081 class AARBoundingBox : public BoundingBox<T,Boolean,Float> {
00082 private:
00083   typedef AARBoundingBox<T,Boolean,Float,BoxType> self;
00084   typedef BoundingBox<T,Boolean,Float> base;
00085 
00086 public:
00088   AARBoundingBox() { }
00089 
00091   AARBoundingBox(T xlow, T ylow, T xhigh, T yhigh )
00092     : box(xlow,ylow,xhigh,yhigh) { }
00093 
00096   AARBoundingBox(T centerx, T centery, T radius )
00097     : box(centerx-radius,centery-radius,centerx+radius,centery+radius) { }
00098   
00099   virtual Boolean inside(T x, T y) const {  return box.inside(x,y);  }
00100 
00102   virtual self& set() {  box.set(); return *this;  }
00103 
00105   virtual self& set(T xlow, T ylow, T xhigh, T yhigh) 
00106     {  box=BoxType(xlow,ylow,xhigh,yhigh); return *this;  }
00107 
00109   virtual self& operator+=( const self& b )
00110     {  box += b.box;  return *this;  }
00111   
00112   virtual base& scale( T xscale, T yscale )
00113     {  box.scale(xscale,yscale);  return *this;  }
00114   
00117   virtual base& rotate( Float theta ) {  box.rotate(theta);  return *this;  }
00118 
00119   virtual base& translate( T xoffset, T yoffset )
00120     {  box.translate(xoffset,yoffset);  return *this;  }
00121 
00122   virtual typename base::Rectangle aarectangle() const
00123     {  return (box.isinfinite()? typename base::Rectangle() : box.aarectangle());  }
00124   
00125   virtual base* clone() const {  return new self(*this); };
00126 
00127   virtual std::ostream& put(std::ostream &s) const
00128     {  return box.put(s); }
00129 
00132   virtual Boolean empty() const
00133     {  return box.empty(); }
00134 
00135 protected:  
00136   BoxType box;
00137 };
00138 
00139 
00140 
00156 template<class T=int,class Boolean=bool,class Float=double,
00157          class BoxType=AAArbitraryRectangle<T,Boolean,Float> >
00158 class BoundingEllipse : public AARBoundingBox<T,Boolean,Float,BoxType> {
00159   typedef BoundingBox<T,Boolean,Float> base;
00160   typedef BoundingEllipse<T,Boolean,Float,BoxType> self;
00161   typedef AARBoundingBox<T,Boolean,Float> aarbase;
00162   
00163 public:
00165   BoundingEllipse() : aarbase(), trimx(0), trimy(0) { }
00166   
00168   BoundingEllipse(T centerx, T centery, T radius, Float trim=0 )
00169     : aarbase(centerx-radius,centery-radius,centerx+radius,centery+radius),
00170     trimx(trim), trimy(trim) { }
00171 
00173   BoundingEllipse(T centerx, T centery, T radiusx, T radiusy, Float trimx_i=0, Float trimy_i=0)
00174     : aarbase(centerx-radiusx,centery-radiusy,centerx+radiusx,centery+radiusy),
00175     trimx(trimx_i), trimy(trimy_i) { }
00176   
00179   virtual Boolean inside(T x, T y) const {
00180     if (box.isinfinite()) return true;
00181     
00182     /* These could be cached */
00183     const Float radiusx         = (box.width())/2.0+trimx;
00184     const Float radiusy         = (box.height())/2.0+trimy;
00185     const Float div_radiusx_sq  = 1/(radiusx*radiusx);
00186     const Float div_radiusy_sq  = 1/(radiusy*radiusy);
00187     const T centerx             = box.corners().xl+T(radiusx);
00188     const T centery             = box.corners().yl+T(radiusy);
00189     
00190     const T xdistance           = x-centerx;
00191     const T ydistance           = y-centery;
00192     const T xdistance_sq        = xdistance*xdistance;
00193     const T ydistance_sq        = ydistance*ydistance;
00194 
00195     return (xdistance_sq*div_radiusx_sq + ydistance_sq*div_radiusy_sq < 1);
00196   }
00197 
00198 
00200   virtual base& rotate( Float theta ) {
00201     (void)theta;
00202     /* This routine should be straightforward to implement, since it would
00203        just need to rotate each corner about the center.   However, it would
00204        be tedious to do, and the inside() routine would need to be modified
00205        to match.  So it is left undone since this routine is not
00206        currently needed.
00207     */
00208     abort();
00209     return *this;
00210   }
00211 
00212   virtual base* clone() const {  return new self(*this); }
00213 
00214 private:
00215   Float trimx,trimy;
00216 };
00217 
00218 
00221 template<class T=int,class Boolean=bool,class Float=double,
00222          class BBA=BoundingEllipse<T,Boolean,Float>,
00223          class BBB=AARBoundingBox<T,Boolean,Float> >
00224 class Intersection : public BoundingBox<T,Boolean,Float> {
00225   typedef BoundingBox<T,Boolean,Float> base;
00226   typedef Intersection<T,Boolean,Float,BBA,BBB> self;
00227   typedef AARBoundingBox<T,Boolean,Float> aarbase;
00228   
00229 public:
00231   Intersection(const BBA& bb_a=BBA(), const BBB& bb_b=BBB())
00232     : a(bb_a), b(bb_b) { }
00233   
00236   virtual Boolean inside(T x, T y) const 
00237     {  return (a.inside(x,y) && b.inside(x,y));  }
00238 
00240   virtual base& scale(T xscale, T yscale)
00241     {  a.scale(xscale,yscale); b.scale(xscale,yscale);  return *this;  }
00242 
00244   virtual base& rotate(Float angle)
00245     {  a.rotate(angle); b.rotate(angle);  return *this;  }
00246 
00248   virtual base& translate(T xoffset, T yoffset)
00249     {  a.translate(xoffset,yoffset); b.translate(xoffset,yoffset);  return *this;  }
00250   
00253   virtual typename base::Rectangle aarectangle() const {  return a.aarectangle().intersection(b.aarectangle());  }
00254 
00255   virtual base* clone() const {  return new self(*this); };
00256 
00257   virtual std::ostream& put(std::ostream &s) const
00258     {  s<<"(";  a.put(s);  s<<" && ";  b.put(s);  s<<")";  return s;  };
00259   
00260 private:
00261   BBA a;
00262   BBB b;
00263 };
00264 
00265 
00266 
00268 template<class T=int,class Boolean=bool,class Float=double>
00269 class BoundingCircle : public BoundingBox<T,Boolean,Float> {
00270 private:
00271   typedef BoundingCircle<T,Boolean,Float> self;
00272   typedef BoundingBox<T,Boolean,Float> base;
00273 
00274 public:
00276   BoundingCircle(): infinite(true) { }
00277 
00279   BoundingCircle(T centerx_, T centery_, Float radius_ )
00280     : infinite(false), centerx(centerx_), centery(centery_), radius(radius_)
00281     {  freshencache();  }
00282 
00283   inline Boolean isinfinite() const {  return infinite;  }
00284   
00285   virtual Boolean inside(T x, T y) const {
00286     if (isinfinite()) return true;
00287     
00288     const T xdistance           = x-centerx;
00289     const T ydistance           = y-centery;
00290     const T xdistance_sq        = xdistance*xdistance;
00291     const T ydistance_sq        = ydistance*ydistance;
00292 
00293     return (xdistance_sq + ydistance_sq <= radius_sq);
00294   }
00295 
00297   virtual base& scale( T xscale, T yscale )
00298     {  radius*=xscale; (void)yscale; assert(xscale==yscale);  freshencache();  return *this;  }
00299   
00301   virtual base& rotate( Float ) {  return *this;  }
00302 
00303   virtual base& translate( T xoffset, T yoffset )
00304     {  centerx+=xoffset;  centery+=yoffset;  freshencache();  return *this;  }
00305 
00308   virtual typename base::Rectangle aarectangle() const {
00309     return (isinfinite()?
00310             typename base::Rectangle() :
00311             typename base::Rectangle(T(centerx)-T(radius),T(centery)-T(radius),
00312                                      T(centerx)+T(radius),T(centery)+T(radius)));
00313   }
00314   
00315   virtual base* clone() const {  return new self(*this); };
00316 
00317   virtual std::ostream& put(std::ostream &s) const
00318     {  return (s << "((" << centerx << "," << centery << ") radius " << radius << ")");  }
00319 
00320 private:
00321   Boolean infinite;
00322 
00323   T centerx;
00324   T centery;
00325   Float radius;
00326 
00327   /* \name Cached values computed from radius,radiusy and centerx,centery */
00329   Float radius_sq;
00330   void freshencache() {  radius_sq = radius*radius;  }
00332 };
00333 
00334 
00335 
00336 
00337 } /* namespace Boundary */
00338 
00339 // For temporary backwards compatibility
00340 using namespace Boundary;
00341 
00342 #endif /* __BOUNDINGBOX_H__ */

Generated on Mon Jan 20 02:35:43 2003 for RF-LISSOM by doxygen1.3-rc2