bounds.h

00001 /* MLPACK 0.2
00002  *
00003  * Copyright (c) 2008, 2009 Alexander Gray,
00004  *                          Garry Boyer,
00005  *                          Ryan Riegel,
00006  *                          Nikolaos Vasiloglou,
00007  *                          Dongryeol Lee,
00008  *                          Chip Mappus, 
00009  *                          Nishant Mehta,
00010  *                          Hua Ouyang,
00011  *                          Parikshit Ram,
00012  *                          Long Tran,
00013  *                          Wee Chin Wong
00014  *
00015  * Copyright (c) 2008, 2009 Georgia Institute of Technology
00016  *
00017  * This program is free software; you can redistribute it and/or
00018  * modify it under the terms of the GNU General Public License as
00019  * published by the Free Software Foundation; either version 2 of the
00020  * License, or (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful, but
00023  * WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  * General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00030  * 02110-1301, USA.
00031  */
00043 #ifndef TREE_BOUNDS_H
00044 #define TREE_BOUNDS_H
00045 
00046 #include "fastlib/la/matrix.h"
00047 #include "fastlib/la/la.h"
00048 
00049 #include "fastlib/math/math_lib.h"
00050 
00056 template<int t_pow = 2>
00057 class DHrectBound {
00058  public:
00059   static const int PREFERRED_POWER = t_pow;
00060 
00061  private:
00062   DRange *bounds_;
00063   index_t dim_;
00064 
00065   OBJECT_TRAVERSAL(DHrectBound) {
00066     OT_OBJ(dim_);
00067     OT_ALLOC(bounds_, dim_);
00068   };
00069 
00070  public:
00075   void Init(index_t dimension) {
00076     //DEBUG_ASSERT_MSG(dim_ == BIG_BAD_NUMBER, "Already initialized");
00077     bounds_ = mem::Alloc<DRange>(dimension);
00078 
00079     dim_ = dimension;
00080     Reset();
00081   }
00082   
00090   void AverageBoxesInit(const DHrectBound& box1, const DHrectBound& box2) {
00091   
00092     index_t dim = box1.dim();
00093     DEBUG_ASSERT(dim == box2.dim());
00094     
00095     Init(dim);
00096     
00097     for (index_t i = 0; i < dim; i++) {
00098     
00099       DRange range;
00100       range = box1.get(i) +  box2.get(i);
00101       range *= 0.5;
00102       bounds_[i] = range;
00103     
00104     } 
00105     
00106   } // AverageBoxes()
00107 
00111   void Reset() {
00112     for (index_t i = 0; i < dim_; i++) {
00113       bounds_[i].InitEmptySet();
00114     }
00115   }
00116 
00120   bool Contains(const Vector& point) const {
00121     for (index_t i = 0; i < point.length(); i++) {
00122       if (!bounds_[i].Contains(point[i])) {
00123         return false;
00124       }
00125     }
00126 
00127     return true;
00128   }
00129 
00130   bool Contains(const Vector& point, const Vector& box) const {
00131     const DRange *a = this->bounds_;
00132     for (index_t i = 0; i < point.length(); i++){
00133       if (a[i].hi > a[i].lo){
00134         if (!bounds_[i].Contains(point[i])){
00135           return false;
00136         }
00137       } else if(point[i] > a[i].hi & point[i] < a[i].lo){
00138         return false;
00139       }       
00140     }
00141     return true;
00142   } 
00143 
00144 
00146   index_t dim() const {
00147     return dim_;
00148   }
00149 
00153   const DRange& get(index_t i) const {
00154     DEBUG_BOUNDS(i, dim_);
00155     return bounds_[i];
00156   }
00157   
00161   double CalculateMaxDistanceSq() const {
00162     double max_distance=0;
00163     for (index_t i = 0; i < dim_; i++) {
00164       max_distance+=math::Sqr(bounds_[i].width());
00165     }
00166     return max_distance;  
00167   }
00168   
00170   void CalculateMidpoint(Vector *centroid) const {
00171     centroid->Init(dim_);
00172     for (index_t i = 0; i < dim_; i++) {
00173       (*centroid)[i] = bounds_[i].mid();
00174     }
00175   }
00177   void CalculateMidpointOverwrite(Vector *centroid) const {
00178     for (index_t i = 0; i < dim_; i++) {
00179       (*centroid)[i] = bounds_[i].mid();
00180     }
00181   }
00182 
00183 
00187   double MinDistanceSq(const double *mpoint) const {
00188     double sum = 0;
00189     const DRange *mbound = bounds_;
00190 
00191     index_t d = dim_;
00192 
00193     do {
00194       double v = *mpoint;
00195       double v1 = mbound->lo - v;
00196       double v2 = v - mbound->hi;
00197 
00198       v = (v1 + fabs(v1)) + (v2 + fabs(v2));
00199 
00200       mbound++;
00201       mpoint++;
00202 
00203       sum += math::Pow<t_pow, 1>(v); // v is non-negative
00204     } while (--d);
00205 
00206     return math::Pow<2, t_pow>(sum) / 4;
00207   }
00208 
00213  double MinDistanceSq(const DHrectBound& other, const Vector& offset) const {
00214    double sum = 0;
00215    const DRange *a = this->bounds_;
00216    const DRange *b = other.bounds_;
00217    index_t mdim = dim_;
00218    
00219    DEBUG_SAME_SIZE(dim_, other.dim_);
00220    //Add Debug for offset vector
00221 
00222    for (index_t d = 0; d < mdim; d++) {
00223      double v1 = b[d].lo - offset[d] - a[d].hi;
00224      double v2 = a[d].lo + offset[d] - b[d].lo;
00225 
00226      double v = (v1 + fabs(v1)) + (v2 + fabs(v2));
00227 
00228      sum += math::Pow<t_pow, 1>(v);
00229    } 
00230 
00231    return math::Pow<2, t_pow>(sum) / 4;
00232  }
00233 
00237   double MinDistanceSq(const Vector& point) const {
00238     DEBUG_SAME_SIZE(point.length(), dim_);
00239     return MinDistanceSq(point.ptr());
00240   }
00241 
00247   double MinDistanceSq(const DHrectBound& other) const {
00248     double sum = 0;
00249     const DRange *a = this->bounds_;
00250     const DRange *b = other.bounds_;
00251     index_t mdim = dim_;
00252 
00253     DEBUG_SAME_SIZE(dim_, other.dim_);
00254 
00255     for (index_t d = 0; d < mdim; d++) {
00256       double v1 = b[d].lo - a[d].hi;
00257       double v2 = a[d].lo - b[d].hi;
00258       // We invoke the following:
00259       //   x + fabs(x) = max(x * 2, 0)
00260       //   (x * 2)^2 / 4 = x^2
00261       double v = (v1 + fabs(v1)) + (v2 + fabs(v2));
00262 
00263       sum += math::Pow<t_pow, 1>(v); // v is non-negative
00264     }
00265 
00266     return math::Pow<2, t_pow>(sum) / 4;
00267   }
00268 
00269 
00273   double MaxDistanceSq(const Vector& point) const {
00274     double sum = 0;
00275 
00276     DEBUG_SAME_SIZE(point.length(), dim_);
00277 
00278     for (index_t d = 0; d < dim_; d++) {
00279       double v = std::max(point[d] - bounds_[d].lo, bounds_[d].hi - point[d]);
00280       sum += math::Pow<t_pow, 1>(v); // v is non-negative
00281     }
00282 
00283     return math::Pow<2, t_pow>(sum);
00284   }
00285 
00289   double MaxDistanceSq(const double *point) const {
00290     double sum = 0;
00291 
00292     for (index_t d = 0; d < dim_; d++) {
00293       double v = std::max(point[d] - bounds_[d].lo, bounds_[d].hi - point[d]);
00294       sum += math::Pow<t_pow, 1>(v); // v is non-negative
00295     }
00296 
00297     return math::Pow<2, t_pow>(sum);
00298   }
00299 
00303   double MaxDistanceSq(const DHrectBound& other) const {
00304     double sum = 0;
00305     const DRange *a = this->bounds_;
00306     const DRange *b = other.bounds_;
00307 
00308     DEBUG_SAME_SIZE(dim_, other.dim_);
00309 
00310     for (index_t d = 0; d < dim_; d++) {
00311       double v = std::max(b[d].hi - a[d].lo, a[d].hi - b[d].lo);
00312       sum += math::PowAbs<t_pow, 1>(v); // v is non-negative
00313     }
00314 
00315     return math::Pow<2, t_pow>(sum);
00316   }
00317 
00321  double MaxDistanceSq(const DHrectBound& other, const Vector& offset) const {
00322     double sum = 0;
00323     const DRange *a = this->bounds_;
00324     const DRange *b = other.bounds_;
00325 
00326     DEBUG_SAME_SIZE(dim_, other.dim_);
00327 
00328     for (index_t d = 0; d < dim_; d++) {
00329       double v = std::max(b[d].hi + offset[d] - a[d].lo, 
00330                           a[d].hi - offset[d] - b[d].lo);
00331       sum += math::PowAbs<t_pow, 1>(v); // v is non-negative
00332     }
00333 
00334     return math::Pow<2, t_pow>(sum);
00335   }
00336 
00341  double PeriodicMinDistanceSq(const DHrectBound& other, const Vector& box_size)
00342  const {
00343    double sum = 0;
00344    const DRange *a = this->bounds_;
00345    const DRange *b = other.bounds_;
00346    
00347    DEBUG_SAME_SIZE(dim_, other.dim_);
00348    
00349    for (index_t d = 0; d < dim_; d++){      
00350      double v = 0, d1, d2, d3;
00351      d1 = (a[d].hi > a[d].lo | b[d].hi > b[d].lo)*
00352        min(b[d].lo - a[d].hi, a[d].lo-b[d].hi);
00353      d2 = (a[d].hi > a[d].lo & b[d].hi > b[d].lo)*
00354        min(b[d].lo - a[d].hi, a[d].lo-b[d].hi + box_size[d]);
00355      d3 = (a[d].hi > a[d].lo & b[d].hi > b[d].lo)*
00356        min(b[d].lo - a[d].hi + box_size[d], a[d].lo-b[d].hi);
00357      v = (d1 + fabs(d1)) + (d2+  fabs(d2)) + (d3 + fabs(d3));
00358      sum += math::Pow<t_pow, 1>(v);
00359    }   
00360    return math::Pow<2, t_pow>(sum) / 4;
00361  }
00362  
00363 
00364  
00365 double PeriodicMinDistanceSq(const Vector& point, const Vector& box_size)
00366  const {
00367    double sum = 0;  
00368    const DRange *b = this->bounds_;
00369       
00370    for (index_t d = 0; d < dim_; d++){
00371      double a = point[d];
00372      double v = 0, bh;
00373      bh = b[d].hi-b[d].lo;
00374      bh = bh - floor(bh / box_size[d])*box_size[d];
00375      a = a - b[d].lo;
00376      a = a - floor(a / box_size[d])*box_size[d];
00377      if (bh > a){
00378        v = min(a - bh, box_size[d]-a);
00379      }
00380      sum += math::Pow<t_pow, 1>(v);
00381    }
00382    
00383    return math::Pow<2, t_pow>(sum);
00384  }
00385  
00386 
00387 
00388 
00393  double PeriodicMaxDistanceSq(const DHrectBound& other, const Vector& box_size)
00394  const {
00395    double sum = 0;
00396    const DRange *a = this->bounds_;
00397    const DRange *b = other.bounds_;
00398    
00399    DEBUG_SAME_SIZE(dim_, other.dim_);
00400    
00401    for (index_t d = 0; d < dim_; d++){
00402      double v = box_size[d] / 2.0;
00403      double dh, dl;
00404      dh = a[d].hi - b[d].lo;
00405      dh = dh - floor(dh / box_size[d])*box_size[d];
00406      dl = b[d].hi - a[d].lo;
00407      dl = dl - floor(dl / box_size[d])*box_size[d];
00408      v = max(min(dh,v), min(dl, v));
00409        
00410      sum += math::PowAbs<t_pow, 1>(v);
00411    }   
00412    return math::Pow<2, t_pow>(sum);
00413  }
00414 
00415 
00416  double PeriodicMaxDistanceSq(const Vector& point, const Vector& box_size)
00417  const {
00418    double sum = 0;
00419    const DRange *a = this->bounds_;  
00420    for (index_t d = 0; d < dim_; d++){
00421      double b = point[d];
00422      double v = box_size[d] / 2.0;
00423      double ah, al;
00424      ah = a[d].hi - b;
00425      ah = ah - floor(ah / box_size[d])*box_size[d];
00426      if (ah < v){
00427        v = ah;
00428      } else {
00429        al = a[d].lo - b;
00430        al = al - floor(al / box_size[d])*box_size[d];
00431        if (al > v){
00432          v = 2*v-al;
00433        }
00434      }
00435      sum += math::PowAbs<t_pow, 1>(v);
00436    }   
00437    return math::Pow<2, t_pow>(sum);
00438  }
00439 
00440 
00441  double MaxDelta(const DHrectBound& other, double box_width, int dim)
00442  const{
00443    const DRange *a = this->bounds_; 
00444    const DRange *b = other.bounds_;
00445    double result = 0.5*box_width;
00446    double temp = b[dim].hi - a[dim].lo;
00447    temp = temp - floor(temp / box_width)*box_width;
00448    if (temp > box_width / 2){
00449      temp = b[dim].lo - a[dim].hi;
00450      temp = temp - floor(temp / box_width)*box_width;
00451      if (temp > box_width / 2){
00452        result = b[dim].hi - a[dim].lo;
00453        result = result - floor(temp / box_width + 1)*box_width;
00454      } 
00455    } else {
00456      result = temp;
00457    }
00458    return result;
00459  }
00460 
00461  double MinDelta(const DHrectBound& other, double box_width, int dim)
00462  const{
00463    const DRange *a = this->bounds_;   
00464    const DRange *b  = other.bounds_;
00465    double result = -0.5*box_width;
00466    double temp = b[dim].hi - a[dim].lo;
00467    temp = temp - floor(temp/  box_width)*box_width;
00468    if (temp > box_width / 2){
00469      temp = b[dim].hi - a[dim].hi;
00470      temp = temp - floor(temp / box_width)*box_width;
00471      if (temp > box_width / 2){
00472        result = temp - box_width;
00473      } 
00474    } else {
00475      temp = b[dim].hi - a[dim].hi;
00476      result = temp - floor(temp / box_width)*box_width;
00477    }
00478    return result;
00479  }
00480 
00481 
00482 
00486   DRange RangeDistanceSq(const DHrectBound& other) const {
00487     double sum_lo = 0;
00488     double sum_hi = 0;
00489     const DRange *a = this->bounds_;
00490     const DRange *b = other.bounds_;
00491     index_t mdim = dim_;
00492 
00493     DEBUG_SAME_SIZE(dim_, other.dim_);
00494 
00495     for (index_t d = 0; d < mdim; d++) {
00496       double v1 = b[d].lo - a[d].hi;
00497       double v2 = a[d].lo - b[d].hi;
00498       // We invoke the following:
00499       //   x + fabs(x) = max(x * 2, 0)
00500       //   (x * 2)^2 / 4 = x^2
00501       double v_lo = (v1 + fabs(v1)) + (v2 + fabs(v2));
00502       double v_hi = -std::min(v1, v2);
00503 
00504       sum_lo += math::Pow<t_pow, 1>(v_lo); // v_lo is non-negative
00505       sum_hi += math::Pow<t_pow, 1>(v_hi); // v_hi is non-negative
00506     }
00507 
00508     return DRange(math::Pow<2, t_pow>(sum_lo) / 4,
00509         math::Pow<2, t_pow>(sum_hi));
00510   }
00511 
00515   DRange RangeDistanceSq(const Vector& point) const {
00516     double sum_lo = 0;
00517     double sum_hi = 0;
00518     const double *mpoint = point.ptr();
00519     const DRange *mbound = bounds_;
00520 
00521     DEBUG_SAME_SIZE(point.length(), dim_);
00522 
00523     index_t d = dim_;
00524     do {
00525       double v = *mpoint;
00526       double v1 = mbound->lo - v;
00527       double v2 = v - mbound->hi;
00528 
00529       sum_lo += math::Pow<t_pow, 1>((v1 + fabs(v1)) + (v2 + fabs(v2)));
00530       sum_hi += math::Pow<t_pow, 1>(-std::min(v1, v2));
00531 
00532       mpoint++;
00533       mbound++;
00534     } while (--d);
00535 
00536     return DRange(math::Pow<2, t_pow>(sum_lo) / 4,
00537                   math::Pow<2, t_pow>(sum_hi));
00538   }
00539 
00551   double MinToMidSq(const DHrectBound& other) const {
00552     double sum = 0;
00553     const DRange *a = this->bounds_;
00554     const DRange *b = other.bounds_;
00555 
00556     DEBUG_SAME_SIZE(dim_, other.dim_);
00557 
00558     for (index_t d = 0; d < dim_; d++) {
00559       double v = b->mid();
00560       double v1 = a->lo - v;
00561       double v2 = v - a->hi;
00562 
00563       v = (v1 + fabs(v1)) + (v2 + fabs(v2));
00564 
00565       a++;
00566       b++;
00567 
00568       sum += math::Pow<t_pow, 1>(v); // v is non-negative
00569     }
00570 
00571     return math::Pow<2, t_pow>(sum) / 4;
00572   }
00573 
00577   double MinimaxDistanceSq(const DHrectBound& other) const {
00578     double sum = 0;
00579     const DRange *a = this->bounds_;
00580     const DRange *b = other.bounds_;
00581     index_t mdim = dim_;
00582 
00583     DEBUG_SAME_SIZE(dim_, other.dim_);
00584 
00585     for (index_t d = 0; d < mdim; d++) {
00586       double v1 = b[d].hi - a[d].hi;
00587       double v2 = a[d].lo - b[d].lo;
00588       double v = std::max(v1, v2);
00589       v = (v + fabs(v)); /* truncate negatives to zero */
00590       sum += math::Pow<t_pow, 1>(v); // v is non-negative
00591     }
00592 
00593     return math::Pow<2, t_pow>(sum) / 4;
00594   }
00595 
00599   double MidDistanceSq(const DHrectBound& other) const {
00600     double sum = 0;
00601     const DRange *a = this->bounds_;
00602     const DRange *b = other.bounds_;
00603 
00604     DEBUG_SAME_SIZE(dim_, other.dim_);
00605 
00606     for (index_t d = 0; d < dim_; d++) {
00607       sum += math::PowAbs<t_pow, 1>(a[d].hi + a[d].lo - b[d].hi - b[d].lo);
00608     }
00609 
00610     return math::Pow<2, t_pow>(sum) / 4;
00611   }
00612 
00616   DHrectBound& operator |= (const Vector& vector) {
00617     DEBUG_SAME_SIZE(vector.length(), dim_);
00618 
00619     for (index_t i = 0; i < dim_; i++) {
00620       bounds_[i] |= vector[i];
00621     }
00622 
00623     return *this;
00624   }
00625 
00629   DHrectBound& operator |= (const DHrectBound& other) {
00630     DEBUG_SAME_SIZE(other.dim_, dim_);
00631 
00632     for (index_t i = 0; i < dim_; i++) {
00633       bounds_[i] |= other.bounds_[i];
00634     }
00635 
00636     return *this;
00637   }
00638 
00639 
00644  DHrectBound& Add(const Vector&  other, const Vector& size){
00645    DEBUG_SAME_SIZE(other.length(), dim_);
00646    // Catch case of uninitialized bounds
00647    if (bounds_[0].hi < 0){
00648      for (index_t i = 0; i < dim_; i++){
00649        bounds_[i] |= other[i];
00650      }
00651    }
00652 
00653    for (index_t i= 0; i < dim_; i++){
00654      double ah, al;
00655      ah = bounds_[i].hi - other[i];
00656      al = bounds_[i].lo - other[i];
00657      ah = ah - floor(ah / size[i])*size[i];
00658      al = al - floor(al / size[i])*size[i];
00659      if (ah < al){
00660        if (size[i] - ah < al){
00661          bounds_[i].hi = other[i];
00662        } else {
00663          bounds_[i].lo = other[i];
00664        }
00665      }     
00666    }
00667    return *this;
00668  }
00669 
00670 
00674  DHrectBound& Add(const DHrectBound& other, const Vector& size){
00675    if (bounds_[0].hi < 0){
00676      for (index_t i = 0; i < dim_; i++){
00677        bounds_[i] |= other.bounds_[i];
00678      }
00679    }
00680 
00681    for (index_t i = 0; i < dim_; i++) {
00682      double ah, al, bh, bl;
00683      ah = bounds_[i].hi;
00684      al = bounds_[i].lo;
00685      bh = other.bounds_[i].hi;
00686      bl = other.bounds_[i].lo;
00687      ah = ah - al;    
00688      bh = bh - al;
00689      bl = bl - al;              
00690      ah = ah - floor(ah / size[i])*size[i];
00691      bh = bh - floor(bh / size[i])*size[i];
00692      bl = bl - floor(bl / size[i])*size[i];
00693 
00694      if (((bh > ah) & (bh < bl | ah > bl )) ||
00695          (bh >= bl & bl > ah & bh < ah -bl + size[i])){
00696        bounds_[i].hi = other.bounds_[i].hi;
00697      }
00698     
00699      if (bl > ah && ((bl > bh) || (bh >= ah -bl + size[i]))){
00700        bounds_[i].lo = other.bounds_[i].lo;
00701      }   
00702 
00703      if (unlikely(ah > bl & bl > bh)){
00704        bounds_[i].lo = 0;
00705        bounds_[i].hi = size[i];
00706      }
00707     
00708 
00709    }   
00710    return *this;
00711  }
00712 
00713 
00714 
00715 };
00716 
00723 template<int t_pow>
00724 class LMetric {
00725  public:
00729   static double Distance(const Vector& a, const Vector& b) {
00730     return math::Pow<1, t_pow>(
00731         la::RawLMetric<t_pow>(a.length(), a.ptr(), b.ptr()));
00732   }
00733 
00741   template<int t_result_pow>
00742   static double PowDistance(const Vector& a, const Vector& b) {
00743     return math::Pow<t_result_pow, t_pow>(
00744         la::RawLMetric<t_pow>(a.length(), a.ptr(), b.ptr()));
00745   }
00746 };
00747 
00756 template<typename TMetric = LMetric<2>, typename TPoint = Vector>
00757 class DBallBound {
00758  public:
00759   typedef TPoint Point;
00760   typedef TMetric Metric;
00761 
00762  private:
00763   double radius_;
00764   TPoint center_;
00765 
00766   OBJECT_TRAVERSAL(DBallBound) {
00767     OT_OBJ(radius_);
00768     OT_OBJ(center_);
00769   }
00770 
00771  public:
00772   double radius() const {
00773     return radius_;
00774   }
00775 
00776   void set_radius(double d) {
00777     radius_ = d;
00778   }
00779 
00780   const TPoint& center() const {
00781     return center_;
00782   }
00783 
00784   TPoint& center() {
00785     return center_;
00786   }
00787 
00791   bool Contains(const Point& point) const {
00792     return MidDistance(point) <= radius_;
00793   }
00794 
00802   void CalculateMidpoint(Point *centroid) const {
00803     ot::InitCopy(centroid, center_);
00804   }
00805 
00809   double MinDistance(const Point& point) const {
00810     return math::ClampNonNegative(MidDistance(point) - radius_);
00811   }
00812 
00813   double MinDistanceSq(const Point& point) const {
00814     return math::Pow<2, 1>(MinDistance(point));
00815   }
00816 
00820   double MinDistance(const DBallBound& other) const {
00821     double delta = MidDistance(other.center_) - radius_ - other.radius_;
00822     return math::ClampNonNegative(delta);
00823   }
00824 
00825   double MinDistanceSq(const DBallBound& other) const {
00826     return math::Pow<2, 1>(MinDistance(other));
00827   }
00828 
00832   double MaxDistance(const Point& point) const {
00833     return MidDistance(point) + radius_;
00834   }
00835 
00836   double MaxDistanceSq(const Point& point) const {
00837     return math::Pow<2, 1>(MaxDistance(point));
00838   }
00839 
00843   double MaxDistance(const DBallBound& other) const {
00844     return MidDistance(other.center_) + radius_ + other.radius_;
00845   }
00846 
00847   double MaxDistanceSq(const DBallBound& other) const {
00848     return math::Pow<2, 1>(MaxDistance(other));
00849   }
00850 
00856   DRange RangeDistance(const DBallBound& other) const {
00857     double delta = MidDistance(other.center_);
00858     double sumradius = radius_ + other.radius_;
00859     return DRange(
00860        math::ClampNonNegative(delta - sumradius),
00861        delta + sumradius);
00862   }
00863 
00864   DRange RangeDistanceSq(const DBallBound& other) const {
00865     double delta = MidDistance(other.center_);
00866     double sumradius = radius_ + other.radius_;
00867     return DRange(
00868        math::Pow<2, 1>(math::ClampNonNegative(delta - sumradius)),
00869        math::Pow<2, 1>(delta + sumradius));
00870   }
00871 
00883   double MinToMid(const DBallBound& other) const {
00884     double delta = MidDistance(other.center_) - radius_;
00885     return math::ClampNonNegative(delta);
00886   }
00887 
00888   double MinToMidSq(const DBallBound& other) const {
00889     return math::Pow<2, 1>(MinToMid(other));
00890   }
00891 
00895   double MinimaxDistance(const DBallBound& other) const {
00896     double delta = MidDistance(other.center_) + other.radius_ - radius_;
00897     return math::ClampNonNegative(delta);
00898   }
00899 
00900   double MinimaxDistanceSq(const DBallBound& other) const {
00901     return math::Pow<2, 1>(MinimaxDistance(other));
00902   }
00903 
00907   double MidDistance(const DBallBound& other) const {
00908     return MidDistance(other.center_);
00909   }
00910 
00911   double MidDistanceSq(const DBallBound& other) const {
00912     return math::Pow<2, 1>(MidDistance(other));
00913   }
00914 
00915   double MidDistance(const Point& point) const {
00916     return Metric::Distance(center_, point);
00917   }
00918 };
00919 
00920 #endif
Generated on Mon Jan 24 12:04:37 2011 for FASTlib by  doxygen 1.6.3