POV-Ray

The Persistence of Vision Raytracer (POV-Ray).

This is the legacy Bug Tracking System for the POV-Ray project. Bugs listed here are being migrated to our github issue tracker. Please refer to that for new reports or updates to existing ones on this system.

Tasklist

FS#59 - Cone intersection test broken

Attached to Project: POV-Ray
Opened by Christoph Lipka (clipka) - Wednesday, 16 September 2009, 19:00 GMT
Last edited by Chris Cason (chrisc) - Thursday, 31 December 2009, 14:14 GMT
Task Type Definite Bug
Category Backend → Geometric Primitives
Status Closed
Assigned To Chris Cason (chrisc)
Operating System All
Severity High
Priority Normal
Reported Version 3.70 beta 34
Due in Version 3.70 beta 35
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

The following scene, showing an almost cylindrical cone floating above a plane, renders fine in POV 3.6.2, but is obviously broken in 3.7.0.beta.34:

camera {
  right     x
  up        y*image_height/image_width
  location  <80,50,40>
  look_at   <0,0,0>
}

light_source { <500,500,500> color rgb 1 }

cone {
  <0,0,30>, 11.303000, <0,0,-30>, 11.302999
  texture { pigment { color rgb 1 } }
}

plane { y, -20 texture { pigment { color rgb 0.3 } } }

The error occurs even with the -MB option, indicating that the problem has nothing to do with bounding, but is in the cone intersection testing code.

This task depends upon

Closed by  Chris Cason (chrisc)
Thursday, 31 December 2009, 14:14 GMT
Reason for closing:  Fixed
Additional comments about closing:  Thanks for the fix!
Comment by Grimbert Jérôme (Le_Forgeron) - Thursday, 17 September 2009, 19:49 GMT

Confirmed, beta 34, from source on linux amd64.

While reading the source of cones.cpp, it seems that a few typo/copy-paste are present since a long time.

Could someone check that the following change would make better sense ?
(does not solve the issue, but it seems to me to be better from the understanding point)

@@ -253,7 +253,7 @@
 
         z = P[Z] + t2 * D[Z];
 
-        if ((t2 > Cone_Tolerance) && (t1 < MAX_DISTANCE) && (z >= 0.0) && (z <= 1.0))
+        if ((t2 > Cone_Tolerance) && (t2 < MAX_DISTANCE) && (z >= 0.0) && (z <= 1.0))
         {
           Intersection[i].d   = t2 / len;
           Intersection[i++].t = SIDE_HIT;
@@ -311,7 +311,7 @@
 
         z = P[Z] + t2 * D[Z];
 
-        if ((t2 > Cone_Tolerance) && (t1 < MAX_DISTANCE) && (z >= dist) && (z <= 1.0))
+        if ((t2 > Cone_Tolerance) && (t2 < MAX_DISTANCE) && (z >= dist) && (z <= 1.0))
         {
           Intersection[i].d   = t2 / len;
           Intersection[i++].t = SIDE_HIT;

For the reported bug, the code between 3.6 and 3.7 for cones is very similar.
So similar that it does not explain the issue.
MAX_DISTANCE & EPSILON are assumed to be the same (looks so here)

The issue is due to the equation solving for a cone: such nearly identical apex & base gives a huge transformation matrix
(the cone object is always in a basic box, apex = 1.0, base = 0.0, base at origin, apex 1 unit away and dist is the distance useful from apex.)
Huge transform, very small dist.

But code is the same (excepted the compilation option ??? do they play a role ?)

Cone_Tolerance moved from 1e-6 to 1e-9, did that matter at such scale/transform ?
(testing in progress)

Comment by Grimbert Jérôme (Le_Forgeron) - Thursday, 17 September 2009, 19:54 GMT

Cone_Tolerance 1e-6, nor 1e-19 did NOT fix the issue.

BTW, the reported max trace level is reported as 0.

Comment by Christoph Lipka (clipka) - Thursday, 17 September 2009, 22:55 GMT

Re the code change suggested by Jerome, I agree: The existing code looks suspiciously like a copy&paste blunder.

Comment by Grimbert Jérôme (Le_Forgeron) - Tuesday, 22 December 2009, 14:11 GMT

In fact, despite the OP's statement, 3.6.1 is also bugged, when the view is adjusted.

camera {
  right     x
  up        y*image_height/image_width
  location  <80,50,40>
  look_at   <0,0,-30>
  angle 78
}

light_source { <500,500,500> color rgb 1 }

cone {
  <0,0,30>, 11.303000, <0,0,-30>, 11.302999 
  texture { pigment { color rgb 1 } }
}

plane { y, -20 texture { pigment { color rgb 2.3 } } }

sphere { <0,0,34>,5
  texture { pigment { color green 1 } }
  }

for the cone (in both versions) Internal data

tlen : 678179999.30286061763763427734
dist: 0.99999991152791289917
base_r: 11.30299899999999979627
apex_r: 11.30300000000000082423
tmpf: 678179939.30286061763763427734
len: 60.00000000000000000000

Now, given the delta of radius/length, I would change the cylinder detector in Compute_Cone_Data from fabs(apex_radius-base_radius) < EPSILON
to
fabs(apex_radius-base_radius)*len/tlen < EPSILON

OP's scene would evaluate to .000000000000088472087238424866928698649637995230318792561639
which is 88.4e-15, far under our current epsilon (1.0e-10).
Problem solved!
(Yes, we are pushing that cone as a cylinder, but could you really see the difference ?)

P.S: as the computation of tlen & len is required beforehand, a reorganisation of the function Compute_Cone_Data is required.

Comment by Grimbert Jérôme (Le_Forgeron) - Tuesday, 29 December 2009, 22:01 GMT

Here a suggestion (tested) for replacement of cones.cpp

   cones.cpp (19.4 KiB)

Loading...