POV-Ray : Newsgroups : povray.general : Regarding "The ray-sphere intersection" macro : Regarding "The ray-sphere intersection" macro Server Time
5 Aug 2024 04:19:41 EDT (-0400)
  Regarding "The ray-sphere intersection" macro  
From: Tor Olav Kristensen
Date: 3 Dec 2002 15:25:48
Message: <3ded134c@news.povray.org>
- which can be found in section 4.2.7 in the
POV-Ray documentation:
http://povray.org/documentation/view/116/

This macro is shown in the advanced SDL tutorial,
where a raytracer is implemented by using only
POV-script.

It is my belief that this macro does some
calulations of values that there is no need for.

Below is my explanation.

Tor Olav


Here is the original macro:

#macro calcRaySphereIntersection(P, D, sphereInd)
  #local V = P-Coord[sphereInd][0];
  #local R = Coord[sphereInd][1].x;

  #local DV = vdot(D, V);
  #local D2 = vdot(D, D);
  #local SQ = DV*DV-D2*(vdot(V, V)-R*R);
  #if(SQ < 0) #local Result = -1;
  #else
    #local SQ = sqrt(SQ);
    #local T1 = (-DV+SQ)/D2;
    #local T2 = (-DV-SQ)/D2;
    #local Result = (T1<T2 ? T1 : T2);
  #end
  Result
#end


If I rewrite it slightly, it looks like this:

#macro calcRaySphereIntersection(pL, vL, pS, R)

  #local vA = pL - pS;
  #local AA = vdot(vA, vA);
  #local AL = vdot(vA, vL);
  #local LL = vdot(vL, vL); // LL > 0
  #local Radicand = AL*AL - LL*(AA - R*R);
  #if (Radicand < 0)
    #local Result = -1;
  #else
    #local SquareRoot = sqrt(Radicand); // SquareRoot >= 0
    #local T1 = (-AL + SquareRoot)/LL;
    #local T2 = (-AL - SquareRoot)/LL;
    #local Result = (T1 < T2 ? T1 : T2);
  #end

  Result

#end // macro calcRaySphereIntersection


Where the arguments to this macro are:
pL: Ray origin (or point on line)
vL: Ray direction (or vector parallel to line)
pS: Sphere centre
R: Sphere radius


Now, this expression:
(T1  <  T2)

can be rewritten like this:
((-AL + SquareRoot)/LL  <  (-AL - SquareRoot)/LL)

Since LL is positive:
(-AL + SquareRoot  <  -AL - SquareRoot)

Adding AL to both sides:
(SquareRoot  <  -SquareRoot)

Since we know that SquareRoot is positive, the
value of this expression must always be false.

Therefore there is no need to calculate the T1
value. (Because it will never be used.)

This means that the macro above can be rewritten
like this:


#macro calcRaySphereIntersection(pL, vL, pS, R)

  #local vA = pL - pS;
  #local AA = vdot(vA, vA);
  #local AL = vdot(vA, vL);
  #local LL = vdot(vL, vL);
  #local Radicand = AL*AL - LL*(AA - R*R);
  #if (Radicand < 0)
    #local Result = -1;
  #else
    #local Result = (-AL - sqrt(Radicand))/LL;
  #end

  Result

#end // macro calcRaySphereIntersection


or like this:

#macro calcRaySphereIntersection(P, D, sphereInd)
  #local V = P-Coord[sphereInd][0];
  #local R = Coord[sphereInd][1].x;
  #local DV = vdot(D, V);
  #local DD = vdot(D, D);
  #local SQ = DV*DV-DD*(vdot(V, V)-R*R);
  #if(SQ < 0)
    #local Result = -1;
  #else
    #local Result = (-DV-sqrt(SQ))/DD;
  #end
  Result
#end


Post a reply to this message

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