|
|
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
|
|