POV-Ray : Newsgroups : povray.programming : sphere scaling bug : Re: sphere scaling bug Server Time
29 Jul 2024 04:20:22 EDT (-0400)
  Re: sphere scaling bug  
From: Dan Connelly
Date: 20 Sep 1998 22:40:41
Message: <3605AE9D.E638F232@flash.net>
Ronald L. Parker wrote:
> 
> Here's the culprit, from the windows config.h file:
> 
> #define EPSILON 1.0e-5
> 
> I changed this to
> 
> #define EPSILON 1.0e-12


Funny : I was just looking over the UNIX code earlier today and
was pretty sure on that system EPSILON was 10^-10 .  It didn't exhibit
the scaling bug, which I had no problem producing on my Windows versions.

But there is another issue, which is how the calculation is done.
A segment of spheres.c follows:

> int Intersect_Sphere(Ray, Center, Radius2, Depth1, Depth2)
> RAY *Ray;
> VECTOR Center;
> DBL Radius2;
> DBL *Depth1, *Depth2;
> {
>   DBL OCSquared, t_Closest_Approach, Half_Chord, t_Half_Chord_Squared;
>   VECTOR Origin_To_Center;
> 
>   Increase_Counter(stats[Ray_Sphere_Tests]);
> 
>   VSub(Origin_To_Center, Center, Ray->Initial);
> 
>   VDot(OCSquared, Origin_To_Center, Origin_To_Center);
> 
>   VDot(t_Closest_Approach, Origin_To_Center, Ray->Direction);
> 
>   if ((OCSquared >= Radius2) && (t_Closest_Approach < EPSILON))
>   {
>     return(FALSE);
>   }
> 
>   t_Half_Chord_Squared = Radius2 - OCSquared + Sqr(t_Closest_Approach);
> 
>   if (t_Half_Chord_Squared > EPSILON)
>   {
>     Half_Chord = sqrt(t_Half_Chord_Squared);
> 
>     *Depth1 = t_Closest_Approach - Half_Chord;
>     *Depth2 = t_Closest_Approach + Half_Chord;
> 
>     Increase_Counter(stats[Ray_Sphere_Tests_Succeeded]);
> 
>     return(TRUE);
>   }
> 
>   return(FALSE);
> }
> 

Note the test : t_Half_Chord_Squared, of order distance^2, 
is compared to epsilon.  I would expect a test of the following
form might be less prone to scaling artifacts :

>   if (t_Half_Chord_Squared > EPSILON * Radius2)

or, equivalently (and faster) :

>   t_Half_Chord_Squared_N = 1 - (CSquared + Sqr(t_Closest_Approach)) / Radius2;
...
>   if (t_Half_Chord_Squared_N > EPSILON)
...
>   Half_Chord = sqrt(Radius2 * t_Half_Chord_Squared_N)

There are many other ways in which one could try and preserve scale
invariance of these tests.

Dan

-- 
http://www.flash.net/~djconnel/


Post a reply to this message

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