POV-Ray : Newsgroups : povray.general : Regarding "The ray-sphere intersection" macro Server Time
17 Nov 2024 23:16:58 EST (-0500)
  Regarding "The ray-sphere intersection" macro (Message 1 to 2 of 2)  
From: Tor Olav Kristensen
Subject: Regarding "The ray-sphere intersection" macro
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

From: Warp
Subject: Re: Regarding "The ray-sphere intersection" macro
Date: 3 Dec 2002 16:38:47
Message: <3ded2467@news.povray.org>
Actually the whole macro can be replaced with a function (which calls
other functions). I tried this once, and by doing this the "rendering"
speeds up by about 30% (IIRC).

  There are other (simple) optimizations that could be added to the code,
such as caching the last shadowing sphere for each light source, but I feel
that would be a bit out of the scope of the tutorial.

-- 
#macro M(A,N,D,L)plane{-z,-9pigment{mandel L*9translate N color_map{[0rgb x]
[1rgb 9]}scale<D,D*3D>*1e3}rotate y*A*8}#end M(-3<1.206434.28623>70,7)M(
-1<.7438.1795>1,20)M(1<.77595.13699>30,20)M(3<.75923.07145>80,99)// - Warp -


Post a reply to this message

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