POV-Ray : Newsgroups : povray.programming : Several blob bugs (job000189) [2] : Several blob bugs (job000189) [2] Server Time
6 Oct 2024 14:00:31 EDT (-0400)
  Several blob bugs (job000189) [2]  
From: Massimo Valentini
Date: 2 Nov 2002 04:12:38
Message: <3dc39706@news.povray.org>
The following patch fixes some bugs reported at 
http://www.povray.org/download/3.5-bugs.php.
In particular it should fix:

http://news.povray.org/3b99052c@news.povray.org (at least the 2nd)
http://news.povray.org/Xns9115B92CF7D8ACQ@204.213.191.226
http://news.povray.org/Xns91203DC7F3CCQ@204.213.191.226
http://news.povray.org/3be5f0b2@news.povray.org

A simple explanation (without formulas) is:

All bug reports concern with big/small blob objects.

Let's represent an object using millimeters as pov unit, we'll
have a direction of 1 mm, and the depth of the intersections will be
in mm. But if you represent the same object in meters, the ray direction
is 1 m long, and the depth of the intersections are now in m. The problem
is that the equations representing these intersections are fourth order
polinomials and it is easy to exceed limits and lose accuracy.

So, when computing the equations I scale ray's direction proportionally 
to a dimension of the object, and then the computed depths 
are scaled back to the original unit.


The patch is against blob.cpp (as it is in povray-3.50a for linux).
If it is not worth to be included in the vanilla-povray (it needs 
extensive tests), I hope it's a good starting point for those interested 
in fix these bugs. 

Comments are welcome.

HTH Massimo

--- src/blob.cpp.ex Sat Nov  2 09:30:34 2002
+++ src/blob.cpp Sat Nov  2 09:30:34 2002
@@ -344,8 +344,11 @@
     start_dist = 0.0;
   }
 
+  DBL Max_Bound = intervals[0].bound;
   for (i = 0; i < cnt; i++)
   {
+    if (intervals[i].bound > Max_Bound) 
+      Max_Bound = intervals[i].bound;
     intervals[i].bound -= start_dist;
   }
 
@@ -353,6 +356,20 @@
 
   VAddScaledEq(P, start_dist, D);
 
+  if (Max_Bound != 0) 
+  {
+    VScaleEq(D, Max_Bound);
+
+    for (i = 0; i < cnt; i++)
+    {
+      intervals[i].bound /= Max_Bound;
+    }
+  }
+  else 
+  {
+    Max_Bound = 1;
+  }
+
   /* Clear out the coefficients. */
 
   coeffs[0] =
@@ -389,6 +406,7 @@
         
           VDot(t0, V1, V1);
           VDot(t1, V1, D);
+          t2 = Max_Bound * Max_Bound;
 
           c0 = Element->c[0];
           c1 = Element->c[1];
@@ -396,9 +414,9 @@
         
           fcoeffs = &(Element->f[0]);
         
-          fcoeffs[0] = c0;
-          fcoeffs[1] = 4.0 * c0 * t1;
-          fcoeffs[2] = 2.0 * c0 * (2.0 * t1 * t1 + t0) + c1;
+          fcoeffs[0] = c0 * t2 * t2;
+          fcoeffs[1] = 4.0 * c0 * t1 * t2;
+          fcoeffs[2] = 2.0 * c0 * (2.0 * t1 * t1 + t0 * t2) + c1 * t2;
           fcoeffs[3] = 2.0 * t1 * (2.0 * c0 * t0 + c1);
           fcoeffs[4] = t0 * (c0 * t0 + c1) + c2;
         
@@ -584,7 +602,7 @@
       {
         /* Correct distance. */
 
-        dist = (dist + start_dist) / len;
+        dist = (dist * Max_Bound + start_dist) / len;
 
         if ((dist > DEPTH_TOLERANCE) && (dist < Max_Distance))
         {


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.