[MOAB-dev] bug in MBOrientedBox::intersect_ray

Brandon Smith bsmith82 at yahoo.com
Thu Feb 11 13:26:43 CST 2010


Hi All,

While tracking some lost particles I found a bug in MBOrientedBox::intersect_ray. It was due to subtracting a squared distance. More specifically, the fact that a squared distance becomes larger if the distance is greater than one, but smaller if the distance is less than one (assuming distance is always positive). With Jason's help I tried to make the tolerances used in the test more consistent. Below is a diff of the fix. The fix reduces the number of lost particles by ~50%.

Are there any changes/suggestions to this diff?

Brandon

Index: MBOrientedBox.hpp
===================================================================
--- MBOrientedBox.hpp   (revision 3533)
+++ MBOrientedBox.hpp   (working copy)
@@ -53,8 +53,8 @@
 
   inline double inner_radius() const; //!< radius of inscribed sphere
   inline double outer_radius() const; //!< radius of circumscribed sphere
-  inline double outer_radius_squared() const; //!< square of radius of circumsphere
-  inline double inner_radius_squared() const; //!< square of radius if inscribed sphere
+  inline double outer_radius_squared(const double reps) const; //!< square of (radius+at least epsilon) of circumsphere
+  inline double inner_radius_squared(const double reps) const; //!< square of (radius-epsilon) of inscribed sphere
   inline double volume() const;               //!< volume of box
   inline MBCartVect dimensions() const;       //!< number of dimensions for which box is not flat
   inline double area() const;                 //!< largest side area
@@ -176,24 +176,30 @@
 #endif
 }
 
-double MBOrientedBox::outer_radius_squared() const
+// Add at least epsilon to the radius, before squaring it.
+double MBOrientedBox::outer_radius_squared(const double reps) const
 {
 #if MB_ORIENTED_BOX_OUTER_RADIUS
-  return radius * radius;
+  return (radius+reps)*(radius+reps);
 #elif MB_ORIENTED_BOX_UNIT_VECTORS
-  return length % length;
+  MBCartVect tmp(length[0]+reps,length[1]+reps,length[2]+reps);
+  return tmp % tmp;
 #else
-  const MBCartVect half_diag = axis[0] + axis[1] + axis[2];
+  MBCartVect half_diag = axis[0] + axis[1] + axis[2];
+  half_diag += MBCartVect(reps,reps,reps);
   return half_diag % half_diag;
 #endif
 }
 
-double MBOrientedBox::inner_radius_squared() const
+// Subtract epsilon from the length of the shortest axis, before squaring it.
+double MBOrientedBox::inner_radius_squared(const double reps) const
 {
 #if MB_ORIENTED_BOX_UNIT_VECTORS
-  return length[0] * length[0];
+  return (length[0]-reps) * (length[0]-reps);
 #else
-  return axis[0] % axis[0];
+  MBCartVect tmp = axis[0];
+  tmp -= MBCartVect(reps,reps,reps);
+  return (tmp % tmp);
 #endif
 }
 

Index: MBOrientedBox.cpp
===================================================================
--- MBOrientedBox.cpp   (revision 3533)
+++ MBOrientedBox.cpp   (working copy)
@@ -477,16 +477,27 @@
   const MBCartVect cx = center - b;
   double dist_s = cx % m;
   double dist_sq = cx % cx - (dist_s*dist_s);
-  double max_diagsq = outer_radius_squared();
+  double max_diagsq = outer_radius_squared(reps);
   
     // if greater than the longest diagonal, we don't hit
-  if (dist_sq > max_diagsq+reps)
+  if (dist_sq > max_diagsq)
     return false;
-  if (len && dist_s - max_diagsq > *len)
-    return false;
-  
+
+  // If the closest possible hit is farther than len, we don't want the hit.
+  // Problem: the previous method was wrong because max_diagsq will be greater
+  // then max_diag is max_diag>1 but less than max_diag if max_diag<1.
+  if (len) {
+    if (max_diagsq>1) {
+      if (dist_s - max_diagsq > *len)
+        return false;
+    } else {
+      if (dist_s - 1          > *len)
+        return false;
+    }
+  }
+
     // if smaller than shortest diagonal, we do hit
-  if (dist_sq < inner_radius_squared() - reps && dist_s >= 0.0)
+  if (dist_sq < inner_radius_squared(reps) && dist_s >= 0.0)
     return true;
     
     // get transpose of axes


      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/moab-dev/attachments/20100211/bde7ad44/attachment.htm>


More information about the moab-dev mailing list