#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 }
|
1.2.8.1 written by Dimitri van Heesch,
© 1997-2001