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

LOSR::ExactRaytracer Class Reference

LOSR::ExactRaytracer is an exact raytracer table, using QU trace algorithms. More...

#include <ExactRaytracer.hpp>

Inheritance diagram for LOSR::ExactRaytracer::

List of all members.

Public Methods

 ExactRaytracer (unsigned int inSize=0)
 Construct an exact raytracer of the size given as argument. More...

 ExactRaytracer (const LOSR::OpticalSystem &inOpticalSystem)
 Construct an exact raytracer using an optical system. More...

 ~ExactRaytracer ()
 Destructor (do nothing).

ExactRaytracer& operator= (const LOSR::OpticalSystem &inOpticalSystem)
 Reinitialize the raytracer using the optical system given as argument. More...

void initialize (const LOSR::OpticalSystem &inOpticalSystem)
 Initialize the raytracer using the optical system given as argument. More...

void read (std::istream &ioIs=std::cin)
 Read a QU trace from a C++ input stream. More...

bool trace (ExactRaytracer::iterator inStartingPoint)
 Do the QU trace, backward and forward from the starting point, using actual ray values. More...

bool trace (ExactRaytracer::iterator inStartingPoint, long double inY, long double inU)
 Do the QU trace, backward and forward from the object space, using ray values given. More...

bool traceBackward (ExactRaytracer::iterator inActualEntry, ExactRaytracer::iterator inStopEntry)
 Do backward QU trace from actual entry to ending entry, using next entry values. More...

bool traceForward (ExactRaytracer::iterator inActualEntry, ExactRaytracer::iterator inStopEntry)
 Do forward QU trace from actual entry to ending entry, using previous entry values. More...

void write (std::ostream &ioOs=std::cout) const
 Write a QU trace into a C++ output stream. More...


Detailed Description

LOSR::ExactRaytracer is an exact raytracer table, using QU trace algorithms.

LOSR::ExactRaytracer is an exact raytracer table, using QU trace algorithms. It describes a table containing the entries of the QU table and the methods to do the traces, analysing it and manage it. An exact raytracer usually take an optical system as input, before doing the ray trace. See chapter 6 of {\sl Elements of modern optical design}, Donald C. O'Shea, New York, Wiley, c1985, for details about the QU algorithm.

Author:
Christian Gagné and Julie Beaulieu
Version:
0.2
Date:
9/03/2001


Constructor & Destructor Documentation

ExactRaytracer::ExactRaytracer ( unsigned int inSize = 0 )
 

Construct an exact raytracer of the size given as argument.

Parameters:
inSize   Size of the QU trace.
00349   :
00350   std::vector<QU>(inSize)
00351 { }

ExactRaytracer::ExactRaytracer ( const LOSR::OpticalSystem & inOpticalSystem )
 

Construct an exact raytracer using an optical system.

Parameters:
inOpticalSystem   Optical system to use to build the raytracer.
00359   :
00360   std::vector<QU>(inOpticalSystem.size())
00361 {
00362   initialize(inOpticalSystem);
00363 }


Member Function Documentation

void ExactRaytracer::initialize ( const LOSR::OpticalSystem & inOpticalSystem )
 

Initialize the raytracer using the optical system given as argument.

Parameters:
inOpticalSystem   Optical system to use to build the system.
00385 {
00386   resize(inOpticalSystem.size());
00387   for(unsigned int i=0; i<size(); i++) (*this)[i] = inOpticalSystem[i];
00388 }

ExactRaytracer & ExactRaytracer::operator= ( const LOSR::OpticalSystem & inOpticalSystem )
 

Reinitialize the raytracer using the optical system given as argument.

Returns:
Actual exact raytracer.
Parameters:
inOpticalSystem   Optical system to use to build the raytracer.
00373 {
00374   initialize(inOpticalSystem);
00375   return *this;
00376 }

void ExactRaytracer::read ( std::istream & ioIs = std::cin )
 

Read a QU trace from a C++ input stream.

Parameters:
ioIs   Input stream to read the trace from.
00397 {
00398   char c1 ='\0', c2='\0';
00399   unsigned int sz = 0;
00400   char buf[2048];
00401 
00402   // Extract and ignore the rest of lines starting with a #
00403   for(ioIs >> c1; c1=='#'; ioIs >> c1) ioIs.getline(buf,2048,'\n');
00404   if(!ioIs) throw LOSR_RuntimeErrorM("Premature end of stream!");
00405 
00406   // Looking for the number of surface, between parenthesis
00407   ioIs >> sz >> c2;
00408   if((c1!='(') || (c2!=')')) throw LOSR_RuntimeErrorM("Bad file format!");
00409   resize(sz);
00410 
00411   // Read each surfaces from the stream
00412   for(unsigned int i=0; i<sz; i++) {
00413     if(!ioIs) throw LOSR_RuntimeErrorM("Premature end of stream!");
00414     ioIs >> (*this)[i];
00415   }
00416 }

bool ExactRaytracer::trace ( ExactRaytracer::iterator inStartingPoint,
long double inY,
long double inU )
 

Do the QU trace, backward and forward from the object space, using ray values given.

Returns:
True if there was no total internal reflexion, false if there was.
Parameters:
inStartingPoint   QU entry to start the trace.
inY   Ray height value at the object space.
inU   Ray angle value at the object space.
00492 {
00493 #ifndef NDEBUG
00494   if(begin() == end())
00495     throw LOSR_RuntimeErrorM("Cannot trace from an empty raytracer!");
00496   if(inStartingPoint == end())
00497     throw LOSR_RuntimeErrorM("Cannot trace from the ending iterator of a raytracer!");
00498 #endif // NDEBUG
00499   inStartingPoint->mY    = inY;
00500   inStartingPoint->mSinU = sin(inU);
00501   inStartingPoint->mCosU = cos(inU);
00502   inStartingPoint->mQ    = (inY * inStartingPoint->mCosU) +
00503     (inStartingPoint->mT * inStartingPoint->mSinU);
00504   return trace(inStartingPoint);
00505 }

bool ExactRaytracer::trace ( ExactRaytracer::iterator inStartingPoint )
 

Do the QU trace, backward and forward from the starting point, using actual ray values.

It is assumed that the ray values of the actual entry (Q, sinU and cosU) are correctly set.

Returns:
True if there was no total internal reflexion, false if there was.
Parameters:
inStartingPoint   QU entry to start the trace.
00428 {
00429 #ifndef NDEBUG
00430   if(inStartingPoint == end())
00431     throw LOSR_RuntimeErrorM("Cannot trace from the ending iterator of a raytracer!");
00432 #endif  // NDEBUG
00433 
00434   // Evaluate the values of the actual entry
00435   inStartingPoint->mSinI   = ( inStartingPoint->mQ * inStartingPoint->mC ) + inStartingPoint->mSinU;
00436   inStartingPoint->mCosI   = sqrt( 1.0 - (inStartingPoint->mSinI * inStartingPoint->mSinI) );
00437   // inStartingPoint->mCosI   = cos( asin(inStartingPoint->mSinI) );
00438   inStartingPoint->mSinI_U = ( inStartingPoint->mSinI * inStartingPoint->mCosU ) -
00439     ( inStartingPoint->mCosI * inStartingPoint->mSinU );
00440   inStartingPoint->mCosI_U = ( inStartingPoint->mCosI * inStartingPoint->mCosU ) +
00441     ( inStartingPoint->mSinU * inStartingPoint->mSinI );
00442 
00443   if(inStartingPoint != begin()) {
00444     inStartingPoint->mSinIp = inStartingPoint->mSinI * (inStartingPoint-1)->mN / inStartingPoint->mN;
00445   } else {
00446     inStartingPoint->mSinIp = inStartingPoint->mSinI;
00447   }
00448 
00449   inStartingPoint->mCosIp = sqrt( 1.0 - (inStartingPoint->mSinIp * inStartingPoint->mSinIp) );
00450   // inStartingPoint->mCosIp   = cos( asin(inStartingPoint->mSinIp) );
00451   inStartingPoint->mSinUp = ( inStartingPoint->mCosI_U * inStartingPoint->mSinIp ) -
00452     ( inStartingPoint->mSinI_U * inStartingPoint->mCosIp );
00453   inStartingPoint->mCosUp = ( inStartingPoint->mCosI_U * inStartingPoint->mCosIp ) +
00454     ( inStartingPoint->mSinI_U * inStartingPoint->mSinIp );
00455   inStartingPoint->mQp    = inStartingPoint->mQ *
00456     ( inStartingPoint->mCosUp + inStartingPoint->mCosIp ) /
00457     ( inStartingPoint->mCosU + inStartingPoint->mCosI );
00458 
00459   //inStartingPoint->mY = inStartingPoint->mQ * (1.0 + inStartingPoint->mCosI_U) /
00460   //  (inStartingPoint->mCosU + inStartingPoint->mCosI);
00461   inStartingPoint->mY = (inStartingPoint->mQ - (inStartingPoint->mT * inStartingPoint->mSinU) ) /
00462     (inStartingPoint->mCosU);
00463   inStartingPoint->mU = atan2(inStartingPoint->mSinU,inStartingPoint->mCosU);
00464 
00465   // Do QU for the system
00466   bool lResponse = true;
00467   if((std::fabs(inStartingPoint->mSinI) > 1.0) || (std::fabs(inStartingPoint->mSinU) > 1.0) ||
00468      (std::fabs(inStartingPoint->mCosI) > 1.0) || (std::fabs(inStartingPoint->mCosU) > 1.0) ||
00469      (std::fabs(inStartingPoint->mSinIp) > 1.0) || (std::fabs(inStartingPoint->mSinUp) > 1.0) ||
00470      (std::fabs(inStartingPoint->mCosIp) > 1.0) || (std::fabs(inStartingPoint->mCosUp) > 1.0)) {
00471     lResponse = false;
00472   }
00473   if(inStartingPoint != begin()) {
00474     if(traceBackward(inStartingPoint-1,begin()) == false) lResponse = false;
00475   }
00476   if(inStartingPoint != end()-1) {
00477     if(traceForward(inStartingPoint+1,end()) == false) lResponse = false;
00478   }
00479   return lResponse;
00480 }

bool ExactRaytracer::traceBackward ( ExactRaytracer::iterator inActualEntry,
ExactRaytracer::iterator inStopEntry )
 

Do backward QU trace from actual entry to ending entry, using next entry values.

The actual QU entry ray values must be correctly set before the call.

Returns:
True if there was no total internal reflexion, false if there was.
Parameters:
inActualEntry   y-nu entry from which to do the trace.
inStopEntry   y-nu entry to stop the trace
00518 {
00519 #ifndef NDEBUG
00520   // Misc tests and assertions
00521   if(inActualEntry == end())
00522     throw LOSR_RuntimeErrorM("Cannot trace the ending iterator of a raytracer!");
00523   if(inActualEntry == end()-1)
00524     throw LOSR_RuntimeErrorM("Cannot backtrace the previous-to-ending iterator of a raytracer!");
00525   if((inActualEntry == begin()) && (inActualEntry != inStopEntry))
00526     throw LOSR_RuntimeErrorM("The stop entry iterator is not reacheable!");
00527 #endif  // NDEBUG
00528 
00529   // Get an iterator to the next entry  
00530   iterator lNextEntry = inActualEntry+1;
00531 
00532   // Apply the QU equations
00533   inActualEntry->mSinUp  = lNextEntry->mSinU;
00534   inActualEntry->mCosUp  = lNextEntry->mCosU;
00535   inActualEntry->mQp     = lNextEntry->mQ - ( inActualEntry->mT * inActualEntry->mSinUp );
00536   inActualEntry->mSinIp  = ( inActualEntry->mQp * inActualEntry->mC ) + inActualEntry->mSinUp;
00537   inActualEntry->mCosIp  = sqrt( 1.0 - (inActualEntry->mSinIp * inActualEntry->mSinIp) );
00538   // inActualEntry->mCosIp   = cos( asin(inActualEntry->mSinIp) );
00539   inActualEntry->mSinI_U = ( inActualEntry->mSinIp * inActualEntry->mCosUp ) -
00540     ( inActualEntry->mCosIp * inActualEntry->mSinUp );
00541   inActualEntry->mCosI_U = ( inActualEntry->mCosIp * inActualEntry->mCosUp ) +
00542     ( inActualEntry->mSinUp * inActualEntry->mSinIp );
00543 
00544   if(inActualEntry == begin()) {
00545     inActualEntry->mSinI = inActualEntry->mSinIp;
00546     inActualEntry->mCosI = inActualEntry->mCosIp;
00547     inActualEntry->mSinU = inActualEntry->mSinUp;
00548     inActualEntry->mCosU = inActualEntry->mCosUp;
00549     inActualEntry->mQ    = inActualEntry->mQp;
00550   } else {
00551     inActualEntry->mSinI = inActualEntry->mSinIp * inActualEntry->mN / (inActualEntry-1)->mN;
00552     inActualEntry->mCosI = sqrt( 1.0 - (inActualEntry->mSinI * inActualEntry->mSinI) );
00553     // inActualEntry->mCosI   = cos( asin(inActualEntry->mSinI) );
00554     inActualEntry->mSinU = ( inActualEntry->mCosI_U * inActualEntry->mSinI ) -
00555       ( inActualEntry->mSinI_U * inActualEntry->mCosI );
00556     inActualEntry->mCosU = ( inActualEntry->mCosI_U * inActualEntry->mCosI ) +
00557       ( inActualEntry->mSinI_U * inActualEntry->mSinI );
00558     inActualEntry->mQ    = inActualEntry->mQp * ( inActualEntry->mCosU + inActualEntry->mCosI ) /
00559       ( inActualEntry->mCosUp + inActualEntry->mCosIp );
00560   }
00561 
00562   //inActualEntry->mY = inActualEntry->mQ * (1.0 + inActualEntry->mCosI_U) /
00563   //  (inActualEntry->mCosU + inActualEntry->mCosI);
00564   inActualEntry->mY = (inActualEntry->mQ - (inActualEntry->mT * inActualEntry->mSinU) ) /
00565     (inActualEntry->mCosU);
00566   inActualEntry->mU = atan2(inActualEntry->mSinU,inActualEntry->mCosU);
00567 
00568   // Recursive call to do the y-nu trace
00569   bool lResponse = true;
00570   if(inActualEntry != inStopEntry) lResponse = traceBackward(inActualEntry-1,inStopEntry);
00571   if((std::fabs(inActualEntry->mSinI) > 1.0) || (std::fabs(inActualEntry->mSinU) > 1.0) ||
00572      (std::fabs(inActualEntry->mCosI) > 1.0) || (std::fabs(inActualEntry->mCosU) > 1.0) ||
00573      (std::fabs(inActualEntry->mSinIp) > 1.0) || (std::fabs(inActualEntry->mSinUp) > 1.0) ||
00574      (std::fabs(inActualEntry->mCosIp) > 1.0) || (std::fabs(inActualEntry->mCosUp) > 1.0)) {
00575     lResponse = false;
00576   }
00577   return lResponse;
00578 }

bool ExactRaytracer::traceForward ( ExactRaytracer::iterator inActualEntry,
ExactRaytracer::iterator inStopEntry )
 

Do forward QU trace from actual entry to ending entry, using previous entry values.

The actual QU entry ray values must be correctly set before the call.

Returns:
True if there was no total internal reflexion, false if there was.
Parameters:
inActualEntry   QU entry from which to do the trace.
inStopEntry   y-nu entry to stop the trace.
00591 {
00592 #ifndef NDEBUG
00593   // Misc tests and assertions
00594   if(inActualEntry == end())
00595     throw LOSR_RuntimeErrorM("Cannot trace the ending iterator of a raytracer!");
00596   if(inActualEntry == begin())
00597     throw LOSR_RuntimeErrorM("Cannot forward trace the begining iterator of a raytracer!");
00598   if((inActualEntry == end()-1) && (inActualEntry+1 != inStopEntry))
00599     throw LOSR_RuntimeErrorM("The stop entry iterator is not reacheable!");
00600 #endif // NDEBUG
00601 
00602   // Get an iterator to the previous entry  
00603   iterator lPreviousEntry = inActualEntry-1;
00604 
00605   // Apply the QU equations
00606   inActualEntry->mQ    = lPreviousEntry->mQp + ( lPreviousEntry->mT * lPreviousEntry->mSinUp );
00607   inActualEntry->mSinU = lPreviousEntry->mSinUp;
00608   inActualEntry->mCosU = lPreviousEntry->mCosUp;
00609 
00610   inActualEntry->mSinI   = ( inActualEntry->mQ * inActualEntry->mC ) + inActualEntry->mSinU;
00611   inActualEntry->mCosI   = sqrt( 1.0 - (inActualEntry->mSinI * inActualEntry->mSinI) );
00612   // inActualEntry->mCosI   = cos( asin(inActualEntry->mSinI) );
00613   inActualEntry->mSinI_U = ( inActualEntry->mSinI * inActualEntry->mCosU ) -
00614     ( inActualEntry->mCosI * inActualEntry->mSinU );
00615   inActualEntry->mCosI_U = ( inActualEntry->mCosI * inActualEntry->mCosU ) +
00616     ( inActualEntry->mSinU * inActualEntry->mSinI );
00617   inActualEntry->mSinIp = inActualEntry->mSinI * lPreviousEntry->mN / inActualEntry->mN;
00618   inActualEntry->mCosIp = sqrt( 1.0 - (inActualEntry->mSinIp * inActualEntry->mSinIp) );
00619   // inActualEntry->mCosIp = cos( asin(inActualEntry->mSinIp) );
00620   inActualEntry->mSinUp = ( inActualEntry->mCosI_U * inActualEntry->mSinIp ) -
00621     ( inActualEntry->mSinI_U * inActualEntry->mCosIp );
00622   inActualEntry->mCosUp = ( inActualEntry->mCosI_U * inActualEntry->mCosIp ) +
00623     ( inActualEntry->mSinI_U * inActualEntry->mSinIp );
00624   inActualEntry->mQp    = inActualEntry->mQ *
00625     ( inActualEntry->mCosUp + inActualEntry->mCosIp ) /
00626     ( inActualEntry->mCosU + inActualEntry->mCosI );
00627 
00628   // inActualEntry->mY = inActualEntry->mQ * (1.0 + inActualEntry->mCosI_U) /
00629   //   (inActualEntry->mCosU + inActualEntry->mCosI);
00630   inActualEntry->mY = (inActualEntry->mQ - (inActualEntry->mT * inActualEntry->mSinU) ) /
00631     (inActualEntry->mCosU);
00632   inActualEntry->mU = atan2(inActualEntry->mSinU,inActualEntry->mCosU);
00633 
00634   // Recursive call to do the y-nu trace
00635   bool lResponse = true;
00636   if(inActualEntry+1 != inStopEntry) lResponse = traceForward(inActualEntry+1,inStopEntry);
00637   if((std::fabs(inActualEntry->mSinI) > 1.0) || (std::fabs(inActualEntry->mSinU) > 1.0) ||
00638      (std::fabs(inActualEntry->mCosI) > 1.0) || (std::fabs(inActualEntry->mCosU) > 1.0) ||
00639      (std::fabs(inActualEntry->mSinIp) > 1.0) || (std::fabs(inActualEntry->mSinUp) > 1.0) ||
00640      (std::fabs(inActualEntry->mCosIp) > 1.0) || (std::fabs(inActualEntry->mCosUp) > 1.0)) {
00641     lResponse = false;
00642   }
00643   return lResponse;
00644 }

void ExactRaytracer::write ( std::ostream & ioOs = std::cout ) const
 

Write a QU trace into a C++ output stream.

Parameters:
ioOs   Output stream to write the trace into.
00653 {
00654   ioOs << '(' << size() << ')' << std::endl;
00655   for(unsigned int i=0; i<size(); i++) {
00656     ioOs << (*this)[i];
00657   }
00658 }


The documentation for this class was generated from the following files:
Generated at Sat Dec 22 10:58:16 2001 for Library for Optical Systems Raytracing by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001