Salome HOME
[TetraIntersect] Avoid multiple divisions in calculatePolygonBarycenter
authorBRUNO LATHUILIERE <bruno.lathuiliere@edf.fr>
Wed, 21 Feb 2024 11:58:25 +0000 (12:58 +0100)
committerabn <adrien.bruneton@cea.fr>
Wed, 28 Feb 2024 19:54:27 +0000 (20:54 +0100)
+ more accurate (if no overflow) and faster
+ cosmetics floating point fixes

src/INTERP_KERNEL/TransformedTriangle.cxx
src/INTERP_KERNEL/TransformedTriangle.hxx
src/INTERP_KERNEL/TransformedTriangleMath.cxx

index 65ada4f2c6ca27d4fe006c5a776e78dbeab39343..4b18920459bb3980300a9a93a6c33766f9e68211 100644 (file)
@@ -646,20 +646,19 @@ namespace INTERP_KERNEL
       const std::size_t m = polygon.size();
 
       for(int j = 0 ; j < 3 ; ++j)
-        {
-          barycenter[j] = 0.0;
-        }
+       barycenter[j] = 0.0;
+
+      for(std::size_t i = 0 ; i < m ; ++i)
+       {
+         const double* pt = polygon[i];
+         for(int j = 0 ; j < 3 ; ++j)
+           barycenter[j] += pt[j];
+       }
 
       if(m != 0)
         {
-          for(std::size_t i = 0 ; i < m ; ++i)
-            {
-              const double* pt = polygon[i];
-              for(int j = 0 ; j < 3 ; ++j)
-                {
-                  barycenter[j] += pt[j] / double(m);
-                }
-            }
+         for(int j = 0 ; j < 3 ; ++j)
+           barycenter[j] = barycenter[j] / double(m);
         }
       LOG(3,"Barycenter is " << vToStr(barycenter));
     }
index b2ce44315b46dc094fee85974a5c0290200539d3..14d3965971dcb9acac94607b62b5fa67de3fff79 100644 (file)
@@ -512,7 +512,7 @@ namespace INTERP_KERNEL
       if (std::fabs(t1+t2) < THRESHOLD_F*MULT_PREC_F)
         return false;
 
-    return (t1*t2 <= 0.0) && !epsilonEqual(t1,t2, (double)MULT_PREC_F);
+    return (t1*t2 <= 0.0) && !epsilonEqual(t1,t2, MULT_PREC_F);
   }
 
   inline bool TransformedTriangle::testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const
index 30ecbc62177b0bbeedeb32b0c4c04f991ce3c692..7b3eba4e819dfc4a1459bcbbfa5fd5bb8d742d37 100644 (file)
@@ -331,7 +331,7 @@ namespace INTERP_KERNEL
           {
             // this value will not be used - we set it to whatever
             LOG(6, "Triple product not calculated for corner " << corner );
-            _tripleProducts[corner] = -3.14159265;
+            _tripleProducts[corner] = std::nan("triplep");
             _validTP[corner] = false;
           }
         anglesForRows.clear();
@@ -390,11 +390,9 @@ namespace INTERP_KERNEL
     
     //? is this more stable? -> no subtraction
     //    return asin( dotProd / ( lenNormal * lenEdgeVec ) ) + 3.141592625358979 / 2.0;
-    double tmp=dotProd / ( lenNormal * lenEdgeVec );
-    tmp=std::max(tmp,-1.);
-    tmp=std::min(tmp,1.);
-    return atan(1.0)*4.0 - acos(tmp);
-
+    const double tmp=dotProd / ( lenNormal * lenEdgeVec );
+    const double safe_tmp=std::max(std::min(tmp,1.),-1.);
+    return M_PI - std::acos(safe_tmp);
   }
 
   /**