Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Intersection.cxx

Go to the documentation of this file.
00001 // $Id: Intersection.cxx,v 1.1.1.1 1999/12/20 22:28:06 burnett Exp $
00002 //
00003 
00004 #include "geometry/Intersection.h"
00005 #include <cmath>
00006 #include <cfloat>
00007 #include <cassert>
00008 
00009 static double step_parameter = 0.5;  // amount of curvature to step, in radians
00010 static double tolerance = 2e-8;     // how close is close enough (should be same as in Volume)
00011 
00012 double
00013 Intersection::distance(double maxStep, int sign)
00014 {
00015 #if 0 // play with this later
00016     double side = surf.how_near(ray.position()); // initial side
00017     assert( side*sign >= -1e-6);   // must be on correct side??
00018 #endif
00019 
00020     // Step along the ray to find an intersection.
00021     // If sign + the leaving solutions are returned; if sign - entering sol. returned.
00022 
00023     double step = surf.distance(ray.position(), ray.direction(0), sign);
00024 
00025     // In case the ray is straight by-pass iterations and use exact solutions
00026 
00027     double curvature = ray.curvature();
00028     if(curvature == 0 ) return step ;
00029 
00030     // curved ray: make finite steps according to curvature until straight-line estimate is
00031     // within step
00032     double delta = step_parameter/fabs(curvature); // maximum step is 0.5 radian
00033     double start = 0;  // start of current step
00034 
00035     while( step > delta ) {
00036         if( (start += delta) > maxStep) {
00037             // step is too far: if cut back, must still be on same side
00038             double test = surf.how_near(ray.position(maxStep));
00039             if( test*sign < 0 ) {
00040                 // here if crossed boundary at maxStep, but distance missed
00041                 start = maxStep;
00042                 step = surf.distance(ray.position(start), ray.direction(start), sign);
00043                 break;
00044             }
00045             // conclude that surface is unreachable
00046             return FLT_MAX;
00047         }
00048         step = surf.distance(ray.position(start), ray.direction(start), sign);
00049     }
00050     if(step==FLT_MAX) return FLT_MAX;
00051 
00052     // close: now iterate to precise solution
00053     while (fabs(step) > tolerance ) {
00054         start += step;
00055         double next_step = surf.distance(ray.position(start), ray.direction(start), sign);
00056         if( next_step == FLT_MAX) {
00057             double test = surf.how_near(ray.position(maxStep));
00058             assert(  test*sign > -tolerance);
00059             return FLT_MAX; //give up
00060         }else if(next_step >0 && start> maxStep ) {
00061             // prevent runaway
00062             double test = surf.how_near(ray.position(maxStep));
00063             assert(  test*sign > 0 );
00064             return FLT_MAX;
00065         }
00066 
00067         if ( fabs(next_step) > fabs(step) )
00068             next_step = step;
00069         step = next_step;
00070     }
00071     start += step;
00072 #ifdef _DEBUG
00073     double test = surf.how_near(ray.position(start));
00074     assert( fabs(test) < 1e-6);
00075 #endif
00076     return start;
00077 }

Generated at Wed Nov 21 12:20:12 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000