|
![](/i/fill.gif) |
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
|
![](/i/fill.gif) |