|
|
Included is a scene file (as simple as I could make it) that exhibits a bug. I
am not quite sure about its nature, but this is what I've discovered:
* The bug causes cones to be placed erroneously;
* It affects cones, but cylinders are unaffected;
* Increasing the number of segments amplifies the effect;
* Making cone radii constant eliminates the effect;
* Increasing the randomness does not amplify the effect but rather gives
different patterns of misalignment (?);
* Using the same randomness on all axes eliminates the effect, it is more
visible when the axes have more different randomness;
* Two rand seeds with which I've observed the effect are 1322 and 1342
* It seems to be caused by using more than 2 decimal places in cone point
coordinates and/or radii, less than 2 decimal places -> no errors;
My script otputs cone statements to a file; when more than 2 decimal places are
used, the effect is also seen when rendering this file. Inspection of the
coordinates shows that they are correct (cone end coordinate = next cone start
coordinate), therefore the error is not in my script.
I tested it on several machines, with POVWin 3.1 and POVDOS 3.1
Margus
//BEGIN SCENE
camera {orthographic location <0,1,2> up 60*.75*y right 60*x look_at z*2}
light_source {<20,60,-10> color 1}
#include "colors.inc"
//NumSegm number of segments
//RND randomness in X,Y and Z directions (vector expression)
//Seed random number seed
#macro Worm(NumSegm, RND, Seed)
#declare CurSegm = 0;
#declare PointStart = <0,0,0>; //Segment start point
#declare PointEnd = <0,0,1>; //Segment end point
#declare RadStart = 1; //Segment start radius
#declare R1 = seed(Seed);
#fopen TMP "wrmtemp.inc" write
#declare DP = 3; //decimal places of start/end point coordinates
#declare DR = 3; //decimal places of start/end radii
union {
#while (CurSegm < NumSegm)
#declare CurSegm=CurSegm+1;
#declare RadEnd = 1-CurSegm/NumSegm;
cone {PointStart, RadStart, PointEnd, RadEnd}
#declare PointNew=PointEnd+vrotate(PointEnd-PointStart,
<RND.x*(rand(R1)-0.5),
RND.y*(rand(R1)-0.5),
RND.z*(rand(R1)-0.5)>);
#write (TMP, "cone {<",str(PointStart.x,0,DP)",",
str(PointStart.y,0,DP)",",
str(PointStart.z,0,DP)">,",
str(RadStart,0,DR),",<",
str(PointEnd.x,0,DP)",",
str(PointEnd.y,0,DP)",",
str(PointEnd.z,0,DP)">,",
str(RadEnd,0,DR),
" pigment{Red} finish{ambient .3}}\n")
#declare PointStart=PointEnd;
#declare PointEnd=PointNew;
#declare RadStart=RadEnd;
#end}
#end
object {Worm(350,<0,1,0>,1322) pigment{Red} finish{ambient .3}}
Post a reply to this message
|
|
|
|
Hi Margus,
It appears to me that this is not a bug, but rather is a visible effect
of the limitations on the precision of floating-point operations in
hardware.
The objects are being correctly parsed by POV-Ray, but during the
tracing computations there are problems with the magnitude of the values
the program must handle. Each cone has a "Trans" (transformation)
matrix defined, which describes the placement of the object in the
coordinate space. The "Trans" matrix and its inverse given below are
for the first misplaced segment of the "worm" shape in my rendering.
(I've modified the scene somewhat, so don't be alarmed if you're crazy
enough to check them and find they don't match!!)
matrix
0.99714285714286 0.00000000000000 0.00000000000000
0.00000000000000
0.00000000000000 -0.99714285714286 1.2211074785257e-016
0.00000000000000
0.00000000000000 -1.7095504699361e-013 -1396.0000000000
0.00000000000000
-0.81466897165920 0.00000000000000 1399.9997622903
1.0000000000000
inverse
1.0028653295129 0.00000000000000 0.00000000000000
0.00000000000000
0.00000000000000 -1.0028653295129 -8.7722518182116e-020
0.00000000000000
0.00000000000000 1.2281152545497e-016 -0.00071633237822348
0.00000000000000
0.81700326670694 -1.7193610644346e-013 1.0028651592337
1.0000000000000
There are 19 orders of magnitude between the smallest and largest values
in "matrix". The x86 series floating point unit has a precision of
about 16-20 significant figures (I think), so most computations
(especially addition and subtraction) involving numbers of this
magnitude are going to suffer a severe loss of significant figures.
Given the way POV-Ray handles the cone primitive, there are two things
that worsen the problem:
- Having the axis of the cone coincide nearly (but not exactly) with the
Z-coordinate axis (I'm not sure why it's only the Z axis), and
- Having the sides of the cone very nearly (but not quite) parallel to
each other (ie. the two radii nearly equal).
Your 'worm' shape unfortunately has both of these characteristics.
Cylinders use a different method of computation and will not suffer from
the same problem. Although they are not entirely immune to the effects
of floating-point precision, they are less prone to error under similar
circumstances. Cones with equal radii are treated by POV-Ray the same
as cylinders and hence do not have this problem.
I can't find any way of proving that it's a floating point precision
problem, but it's got all the characteristics of one.
Cheers,
Darius Davis
Post a reply to this message
|
|
|
|
Dan Connelly wrote:
>
> I strongly suspect this is another manifestation of the
> large #define EPSILON 1E-5 in the config.h of Intel platforms....
My EPSILON is 1E-10, and I've got the same errors.
I believe it's simply due to the hardware. I believe the problem is as
follows:
Calculate 1 + 1e-20, with 20 significant figures. The answer is
1.00000000000000000001, which rounds to 1.0. There is a total loss of
significance. (ie. a 100% error, it's as if the 1e-20 wasn't added in
the first place)
Now, Calculate 1 + 1.4999e-19, with 20 significant figures.
The answer is 1.00000000000000000014999 (if I've got the right number of
zeroes :) and when you round that to 20 significant figures, the answer
is simply 1.0000000000000000001. Now the actual amount added is
1.0e-19. That's a fairly major error (about 33%).
This is essentially the cause of the problem (although the computer
rounds in binary, not decimal), and I don't believe there's anything
that can be done about it other than to change the scene file (or find
and use a more precise floating point type - which would require a
re-design of the CPU...)
I'm still not 100% sure about this diagnosis, but I am fairly confident
in it.
Cheers,
Darius Davis
Post a reply to this message
|
|