00001
00002
00003
00004 #include "geometry/Intersection.h"
00005 #include <cmath>
00006 #include <cfloat>
00007 #include <cassert>
00008
00009 static double step_parameter = 0.5;
00010 static double tolerance = 2e-8;
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());
00017 assert( side*sign >= -1e-6);
00018 #endif
00019
00020
00021
00022
00023 double step = surf.distance(ray.position(), ray.direction(0), sign);
00024
00025
00026
00027 double curvature = ray.curvature();
00028 if(curvature == 0 ) return step ;
00029
00030
00031
00032 double delta = step_parameter/fabs(curvature);
00033 double start = 0;
00034
00035 while( step > delta ) {
00036 if( (start += delta) > maxStep) {
00037
00038 double test = surf.how_near(ray.position(maxStep));
00039 if( test*sign < 0 ) {
00040
00041 start = maxStep;
00042 step = surf.distance(ray.position(start), ray.direction(start), sign);
00043 break;
00044 }
00045
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
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;
00060 }else if(next_step >0 && start> maxStep ) {
00061
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 }