#include <ExactRaytracer.hpp>
Inheritance diagram for LOSR::ExactRaytracer::
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... |
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.
|
Construct an exact raytracer of the size given as argument.
00349 : 00350 std::vector<QU>(inSize) 00351 { } |
|
Construct an exact raytracer using an optical system.
00359 : 00360 std::vector<QU>(inOpticalSystem.size()) 00361 { 00362 initialize(inOpticalSystem); 00363 } |
|
Initialize the raytracer using the optical system given as argument.
00385 { 00386 resize(inOpticalSystem.size()); 00387 for(unsigned int i=0; i<size(); i++) (*this)[i] = inOpticalSystem[i]; 00388 } |
|
Reinitialize the raytracer using the optical system given as argument.
00373 { 00374 initialize(inOpticalSystem); 00375 return *this; 00376 } |
|
Read a QU trace from a C++ input stream.
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 } |
|
Do the QU trace, backward and forward from the object space, using ray values given.
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 } |
|
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.
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 } |
|
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.
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 } |
|
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.
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 } |
|
Write a QU trace into a C++ output stream.
00653 { 00654 ioOs << '(' << size() << ')' << std::endl; 00655 for(unsigned int i=0; i<size(); i++) { 00656 ioOs << (*this)[i]; 00657 } 00658 } |