ContourPointRep.cxx

Go to the documentation of this file.
00001 
00011 // For truncation warning
00012 #ifdef _MSC_VER
00013 #include "msdevstudio/MSconfig.h"
00014 #endif
00015 
00016 #include "ContourPointRep.h"
00017 
00018 #include "axes/AxisModelBase.h"
00019 #include "colorreps/BinToColor.h"
00020 #include "colorreps/BinToColorFactory.h"
00021 #include "datasrcs/DataPointTuple.h"
00022 #include "datasrcs/NTuple.h"
00023 #include "datasrcs/NTupleSorter.h"
00024 #include "graphics/DataView.h"
00025 #include "projectors/NTupleProjector.h"
00026 #include "transforms/PeriodicBinaryTransform.h"
00027 
00028 #include <cassert>
00029 #include <cmath>
00030 
00031 using namespace hippodraw;
00032 
00033 using std::max;
00034 using std::min;
00035 using std::vector;
00036 
00037 ContourPointRep::ContourPointRep ( float size )
00038   : LinePointRep ( size )
00039 {
00040   init ();
00041 }
00042 
00043 ContourPointRep::ContourPointRep ( )
00044   : LinePointRep ( )
00045 {
00046   init();
00047 }
00048 
00049 void
00050 ContourPointRep::
00051 init ()
00052 {
00053   BinToColorFactory * factory = BinToColorFactory::instance ();
00054   m_bin_to_color = factory -> create ( "Rainbow" );
00055   m_name = "Contour"; // need to override what base class did
00056   m_numContours = 6;
00057   m_usingUserValues = false;
00058   m_values.clear();
00059   m_values.reserve ( m_numContours );
00060 }
00061 
00062 ContourPointRep::ContourPointRep( const ContourPointRep & rep )
00063   : LinePointRep ( rep )
00064 {
00065   BinToColor * btc = rep.m_bin_to_color;
00066   m_bin_to_color = btc -> clone ();
00067 
00068   m_numContours = rep.getNumContours();
00069   m_usingUserValues = rep.getUsingUserValues();
00070   m_values.clear();
00071   m_values.reserve ( m_numContours );
00072 }
00073 
00074 ContourPointRep::~ContourPointRep()
00075 {
00076   delete m_bin_to_color;
00077 }
00078 
00079 RepBase * ContourPointRep::clone()
00080 {
00081   return new ContourPointRep ( *this );
00082 }
00083 
00084 const BinToColor *
00085 ContourPointRep::
00086 getValueTransform ( ) const
00087 {
00088   return m_bin_to_color;
00089 }
00090 
00091 void
00092 ContourPointRep::
00093 setValueTransform ( BinToColor * btc )
00094 {
00095   delete m_bin_to_color;
00096   m_bin_to_color = btc;
00097 }
00098 
00099 void ContourPointRep::drawValuesWithStyle ( const TransformBase & tf,
00100                                             ViewBase & vb )
00101 {
00102   // Draw Contour Ticks
00103 
00104   drawContourTicks ( tf, vb, m_values );
00105   
00106   // If number of contour level > 20, simply draw segments
00107   if (m_numContours>20){
00108     try {        
00109       const BinaryTransform & t             
00110         = dynamic_cast < const BinaryTransform & > ( tf );           
00111       
00112       t.transform ( m_x, m_y );          
00113       const Rect & user_rect = vb.getUserRect ();
00114       user_rect.makeInBounds ( m_x, m_y );       
00115       
00116       vb.drawColorLines ( m_x, m_y, m_line_style, m_colorvec, m_size );          
00117     
00118     }
00119     catch ( ... ) {
00120       assert ( false );
00121     }
00122   }
00123 
00124   else {
00125 
00126   // Temporary vectors.
00127   vector <double> temp_x;
00128   vector <double> temp_y; 
00129   vector <Line::Style> temp_s;
00130 
00131   // Current point. ( for line style, only one color used )
00132   Color curC=m_colorvec[0]; 
00133   Line::Style curS;
00134   double curX, curY;
00135 
00136   // This flag is set to true when a following segment is found.
00137   bool found=false;
00138 
00139   // Create a vectors for each loop (each contour level may have
00140   // more than one loops), and draw the polyline
00141   while (!m_x.empty()){
00142     temp_x.clear();
00143     temp_y.clear();
00144     temp_x.push_back(m_x[0]);
00145     temp_x.push_back(m_x[1]);
00146     temp_y.push_back(m_y[0]);
00147     temp_y.push_back(m_y[1]);
00148     curX = m_x[1];
00149     curY = m_y[1];
00150     curS = m_stylevec[1];
00151 
00152     m_x.erase(m_x.begin(), m_x.begin()+2);
00153     m_y.erase(m_y.begin(), m_y.begin()+2);
00154     m_stylevec.erase(m_stylevec.begin(), m_stylevec.begin()+2);
00155    
00156 
00157     // Exit the when a loop is formed.
00158     while(curX!=temp_x[0] || curY!=temp_y[0]){
00159       for (unsigned int i=0; i<m_x.size(); i++) {
00160         // A following segment is found.
00161         if (m_x[i]==curX && m_y[i]==curY && m_stylevec[i]==curS){
00162           found=true;
00163           // Add the segment to the current loop
00164           if (i%2==0){
00165             curX=m_x[i+1];
00166             curY=m_y[i+1];
00167             temp_x.push_back(curX);
00168             temp_y.push_back(curY);
00169             m_x.erase(m_x.begin()+i, m_x.begin()+i+2);
00170             m_y.erase(m_y.begin()+i, m_y.begin()+i+2);
00171             m_stylevec.erase(m_stylevec.begin()+i, m_stylevec.begin()+i+2);
00172           } else {
00173             curX=m_x[i-1];
00174             curY=m_y[i-1];
00175             temp_x.push_back(curX);
00176             temp_y.push_back(curY);
00177             m_x.erase(m_x.begin()+i-1, m_x.begin()+i+1);
00178             m_y.erase(m_y.begin()+i-1, m_y.begin()+i+1);
00179             m_stylevec.erase(m_stylevec.begin()+i-1, m_stylevec.begin()+i+1);
00180           }
00181           break;
00182         }
00183       }
00184       // If a following segment cannot be found, break to avoid infinite loop
00185       if (found) {found=false; continue;}
00186       else break;
00187     }
00188   
00189 
00190     // Draw Lines.
00191     try {
00192       const BinaryTransform & t 
00193         = dynamic_cast < const BinaryTransform & > ( tf );
00194       t.transform (temp_x, temp_y);
00195       const Rect & user_rect = vb.getUserRect ();
00196       user_rect.makeInBounds (temp_x, temp_y);
00197       vb.drawPolyLine(temp_x, temp_y, curS, curC, m_size);
00198       
00199     }
00200     catch ( ... ) {
00201       assert ( false );
00202     }
00203 
00204   } // Back to while(!m_x.empty()), draw next polyline.
00205 
00206   }
00207 
00208 }
00209 
00210 void ContourPointRep::drawValues ( const TransformBase & tf, 
00211                                    ViewBase & vb )
00212 {
00213   // Draw Contour Ticks
00214 
00215   drawContourTicks ( tf, vb, m_values );
00216 
00217   // If number of contour level > 20, simply draw segments
00218   if (m_numContours>20){
00219     try {        
00220       const BinaryTransform & t             
00221         = dynamic_cast < const BinaryTransform & > ( tf );           
00222       
00223       t.transform ( m_x, m_y );          
00224       const Rect & user_rect = vb.getUserRect ();
00225       user_rect.makeInBounds ( m_x, m_y );       
00226       
00227       vb.drawColorLines ( m_x, m_y, m_line_style, m_colorvec, m_size );          
00228     
00229     }
00230     catch ( ... ) {
00231       assert ( false );
00232     }
00233   }
00234 
00235   else {
00236 
00237   // Temporary vectors.
00238   vector <double> temp_x;
00239   vector <double> temp_y; 
00240   vector <Color> temp_c;
00241 
00242   // Current point.
00243   Color curC;
00244   double curX, curY;
00245 
00246   // This flag is set to true when a following segment is found.
00247   bool found=false;
00248 
00249   // Create a vectors for each loop (each contour level may have
00250   // more than one loops), and draw the polyline
00251   while (!m_x.empty()){
00252     temp_x.clear();
00253     temp_y.clear();
00254     temp_x.push_back(m_x[0]);
00255     temp_x.push_back(m_x[1]);
00256     temp_y.push_back(m_y[0]);
00257     temp_y.push_back(m_y[1]);
00258     curX = m_x[1];
00259     curY = m_y[1];
00260     curC = m_colorvec[1];
00261 
00262     m_x.erase(m_x.begin(), m_x.begin()+2);
00263     m_y.erase(m_y.begin(), m_y.begin()+2);
00264     m_colorvec.erase(m_colorvec.begin(), m_colorvec.begin()+2);
00265    
00266 
00267     // Exit the when a loop is formed.
00268     while(curX!=temp_x[0] || curY!=temp_y[0]){
00269       for (unsigned int i=0; i<m_x.size(); i++) {
00270         // A following segment is found.
00271         if (m_x[i]==curX && m_y[i]==curY && m_colorvec[i]==curC){
00272           found=true;
00273           // Add the segment to the current loop
00274           if (i%2==0){
00275             curX=m_x[i+1];
00276             curY=m_y[i+1];
00277             temp_x.push_back(curX);
00278             temp_y.push_back(curY);
00279             m_x.erase(m_x.begin()+i, m_x.begin()+i+2);
00280             m_y.erase(m_y.begin()+i, m_y.begin()+i+2);
00281             m_colorvec.erase(m_colorvec.begin()+i, m_colorvec.begin()+i+2);
00282           } else {
00283             curX=m_x[i-1];
00284             curY=m_y[i-1];
00285             temp_x.push_back(curX);
00286             temp_y.push_back(curY);
00287             m_x.erase(m_x.begin()+i-1, m_x.begin()+i+1);
00288             m_y.erase(m_y.begin()+i-1, m_y.begin()+i+1);
00289             m_colorvec.erase(m_colorvec.begin()+i-1, m_colorvec.begin()+i+1);
00290           }
00291           break;
00292         }
00293       }
00294       // If a following segment cannot be found, break to avoid infinite loop
00295       if (found) {found=false; continue;}
00296       else break;
00297     }
00298   
00299 
00300   // Draw Lines.
00301     try {
00302       const BinaryTransform & t 
00303         = dynamic_cast < const BinaryTransform & > ( tf );
00304       t.transform (temp_x, temp_y);
00305       const Rect & user_rect = vb.getUserRect ();
00306       user_rect.makeInBounds (temp_x, temp_y);
00307       vb.drawPolyLine(temp_x, temp_y, m_line_style, curC, m_size);
00308       
00309     }
00310     catch ( ... ) {
00311       assert ( false );
00312     }
00313 
00314   } // Back to while(!m_x.empty()), draw next polyline.
00315 
00316   }
00317 }
00318 
00319 
00322 void
00323 ContourPointRep::
00324 drawContourTicks ( const TransformBase & tb,
00325                    ViewBase & base,
00326                    const std::vector < double > & values )
00327 {
00328   vector< double > xv;
00329   vector< double > yv;
00330   
00331   unsigned int size = values.size ();
00332   xv.reserve ( size );
00333   yv.reserve ( size );
00334 
00335   DataView & view = dynamic_cast < DataView & > ( base );
00336   const Range & range = view.getRange ( Axes::Z );
00337 
00338   const BinaryTransform & bt 
00339     = dynamic_cast < const BinaryTransform & > ( tb );
00340 
00341   const Rect & view_rect = view.getMarginRect ();
00342  
00343   double tick_length = 6.0;
00344   double y_base =  view_rect.getY() - 15.0;
00345 
00346 
00347   for ( unsigned int i = 0; i < values.size(); i++ ) {
00348     
00349     double user_z = values[i];
00350 
00351     if ( range.excludes ( user_z ) ) continue;
00352 
00353     bt.transformZ ( user_z );
00354     
00355     double view_x = view.userToDrawColor ( user_z );
00356 
00357     xv.push_back ( view_x );
00358     yv.push_back ( y_base );
00359     xv.push_back ( view_x );
00360     yv.push_back ( y_base + tick_length );
00361   
00362   }
00363 
00364   view.drawViewLines ( xv, yv, Line::Solid, false, 0 );
00365 }
00366 
00367 namespace dp = hippodraw::DataPoint3DTuple;
00368 
00369 void
00370 ContourPointRep::
00371 createContours (  const DataSource * ntuple,
00372                   const TransformBase * transform )
00373 {
00374   int size = m_values.size();
00375   assert ( size == m_numContours );
00376 
00377   if ( ntuple -> rows () == 0 ) return;
00378 
00379   double      h [5];
00380   int         sh [5];
00381   double      xh [5];
00382   double      yh [5];
00383   int         m1;
00384   int         m2;
00385   int         m3;
00386   int         case_value;
00387   double      dmin;
00388   double      dmax;
00389   double      x1 = 0.0;
00390   double      x2 = 0.0;
00391   double      y1 = 0.0;
00392   double      y2 = 0.0;
00393   unsigned int i,j;
00394   int         k,m;
00395        
00396   int im[4] = {0,1,1,0};
00397   int jm[4] = {0,0,1,1};
00398         
00399   // Castab = Case Table.
00400   
00401   // castab[0][0][0] ==> all three points of the triangle are below
00402   // the plane of the contour.
00403   // 1 ==> in the plane of the contour.
00404   // 2 ==> above the plane of the contour.
00405   
00406   int castab [3][3][3] =
00407     {
00408       {
00409         {0,0,8},{0,2,5},{7,6,9}
00410       },
00411       {
00412         {0,3,4},{1,0,1},{4,3,0}
00413       },
00414       {
00415         {9,6,7},{5,2,0},{8,0,0}
00416       }
00417     };
00418   const vector < unsigned int > & shape = ntuple -> getShape ();
00419   unsigned int i_size = shape[0];  
00420   unsigned int j_size = shape[1];  
00421   vector < unsigned int > index ( 3 );
00422 
00423   for ( i = 0; i < i_size - 1; i++ ) {
00424 
00425     for ( j = 0; j < j_size - 1; j++ ) {
00426       // For box given by (i,j), (i,j+1), (i+1,j), (i+1,j+1),
00427       // find max and min value.
00428 
00429       double temp1,temp2;
00430       index[0] = i;
00431       index[1] = j;
00432       index[2] = dp::Z;
00433       double tempij = ntuple -> operator [] ( index );
00434 
00435       index[1] = j+1;
00436       double tempij1 = ntuple -> operator [] ( index );
00437 
00438       temp1 = min ( tempij, tempij1 );
00439 
00440       index[0] = i+1;
00441       index[1] = j;
00442       double tempi1j = ntuple -> operator[] ( index );
00443 
00444       index[1] = j+1;
00445       double tempi1j1 = ntuple -> operator [] ( index );
00446       temp2 = min ( tempi1j, tempi1j1 );
00447 
00448       dmin  = min ( temp1, temp2 );
00449       
00450       temp1 = max ( tempij, tempij1 );
00451       temp2 = max ( tempi1j, tempi1j1 );
00452       dmax  = max ( temp1, temp2 );
00453   
00454       if ( dmax >= m_values [0] &&
00455            dmin <= m_values [m_numContours-1] ) {
00456         
00457         for ( k = 0; k < m_numContours; k++ ) {
00458           
00459           double curContour = m_values[k];
00460           
00461           if ( curContour >= dmin &&
00462                curContour <= dmax ) {
00463 
00464             // Contour level k passes through the box.
00465             
00466             for ( m = 4; m >= 0; m--) {
00467               
00468               if ( m > 0 ) {
00469                 
00470                 index[0] = i + im[m-1];
00471                 index[1] = j + jm[m-1];
00472                 index[2] = dp::Z;
00473                 h[m] = ntuple -> operator [] ( index ) - curContour;
00474 
00475                 index[2] = dp::X;
00476                 xh[m] = ntuple -> operator [] ( index );
00477 
00478                 index[2] = dp::Y;
00479                 yh[m] = ntuple -> operator [] ( index );
00480 
00481               } 
00482               
00483               else {
00484                 
00485                 h[0]  = 0.25 * ( h[1] + h[2] + h[3] + h[4] );
00486                 index[0] = i;
00487                 index[1] = j;
00488                 index[2] = dp::X;
00489                 double xij = ntuple -> operator [] ( index );
00490 
00491                 index [0] = i+1;
00492                 double xi1j = ntuple -> operator [] ( index );
00493 
00494                 index[0] = i;
00495                 index[1] = j;
00496                 index[2] = dp::Y;
00497                 double yij = ntuple -> operator [] ( index );
00498 
00499                 index [1] = j+1;
00500                 double yij1 = ntuple -> operator [] ( index );
00501 
00502                 xh[0] = 0.50 * ( xij + xi1j );
00503                 yh[0] = 0.50 * ( yij + yij1 );
00504               }
00505               
00506               if ( h[m] > 0.0 ) {
00507                 sh[m] = 1;
00508               } 
00509 
00510               else if ( h[m] < 0.0 ) {
00511                 sh[m] = -1;
00512               } 
00513 
00514               else {
00515                 sh[m] = 0;
00516               }
00517             
00518             }
00519 
00520 //          // Note: at this stage the relative heights of the corners and the
00521 //          // centre are in the h array, and the corresponding coordinates are
00522 //          // in the xh and yh arrays. The centre of the box is indexed by 0
00523 //          // and the 4 corners by 1 to 4 as shown below.
00524 //          // Each triangle is then indexed by the parameter m, and the 3
00525 //          // vertices of each triangle are indexed by parameters m1,m2,and
00526 //          // m3.
00527 //          // It is assumed that the centre of the box is always vertex 2
00528 //          // though this isimportant only when all 3 vertices lie exactly on
00529 //          // the same contour level, in which case only the side of the box
00530 //          // is drawn.
00531 //          //
00532 //          //
00533 //          //      vertex 4 +-------------------+ vertex 3
00534 //          //               | \               / |
00535 //          //               |   \    m=3    /   |
00536 //          //               |     \       /     |
00537 //          //               |       \   /       |
00538 //          //               |  m=4    0   m=2   |       the centre is vertex 0
00539 //          //               |       /   \       |
00540 //          //               |     /       \     |
00541 //          //               |   /    m=1    \   |
00542 //          //               | /               \ |
00543 //          //      vertex 1 +-------------------+ vertex 2
00544             
00545             for (m=1;m<=4;m++) {
00546               
00547               m1 = m;
00548               m2 = 0;
00549               if (m!=4) {
00550                 m3 = m+1;
00551               } else {
00552                 m3 = 1;
00553               }
00554               
00555               case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1];
00556               
00557               if (case_value!=0) {
00558                 switch (case_value) {
00559                 case 1: // Line between vertices 1 and 2
00560                   x1=xh[m1];
00561                   y1=yh[m1];
00562                   x2=xh[m2];
00563                   y2=yh[m2];
00564                   break;
00565                 case 2: // Line between vertices 2 and 3
00566                   x1=xh[m2];
00567                   y1=yh[m2];
00568                   x2=xh[m3];
00569                   y2=yh[m3];
00570                   break;
00571                 case 3: // Line between vertices 3 and 1
00572                   x1=xh[m3];
00573                   y1=yh[m3];
00574                   x2=xh[m1];
00575                   y2=yh[m1];
00576                   break;
00577                 case 4: // Line between vertex 1 and side 2-3
00578                   x1=xh[m1];
00579                   y1=yh[m1];
00580                   x2=intersect(m2,m3,h,xh);
00581                   y2=intersect(m2,m3,h,yh);
00582                   break;
00583                 case 5: // Line between vertex 2 and side 3-1
00584                   x1=xh[m2];
00585                   y1=yh[m2];
00586                   x2=intersect(m3,m1,h,xh);
00587                   y2=intersect(m3,m1,h,yh);
00588                   break;
00589                 case 6: //  Line between vertex 3 and side 1-2
00590                   x1=xh[m3];
00591                   y1=yh[m3];
00592                   x2=intersect(m1,m2,h,xh);
00593                   y2=intersect(m1,m2,h,yh);
00594                   break;
00595                 case 7: // Line between sides 1-2 and 2-3
00596                   x1=intersect(m1,m2,h,xh);
00597                   y1=intersect(m1,m2,h,yh);
00598                   x2=intersect(m2,m3,h,xh);
00599                   y2=intersect(m2,m3,h,yh);
00600                   break;
00601                 case 8: // Line between sides 2-3 and 3-1
00602                   x1=intersect(m2,m3,h,xh);
00603                   y1=intersect(m2,m3,h,yh);
00604                   x2=intersect(m3,m1,h,xh);
00605                   y2=intersect(m3,m1,h,yh);
00606                   break;
00607                 case 9: // Line between sides 3-1 and 1-2
00608                   x1=intersect(m3,m1,h,xh);
00609                   y1=intersect(m3,m1,h,yh);
00610                   x2=intersect(m1,m2,h,xh);
00611                   y2=intersect(m1,m2,h,yh);
00612                   break;
00613                 default:
00614                   break;
00615                 }
00616                 
00617                 const Range r = m_bin_to_color->getRange();
00618                 double val = curContour;
00619                 
00620                 const BinaryTransform * bt 
00621                   = dynamic_cast < const BinaryTransform * > ( transform );
00622                 bt -> transformZ ( val );
00623 
00624                 if ( ! r.excludes ( val ) ) {
00625                   
00626                   m_x.push_back ( x1 );
00627                   m_x.push_back ( x2 );
00628                   m_y.push_back ( y1 );
00629                   m_y.push_back ( y2 );
00630                 
00631                   // Pushing twice just to ensure symmetry.
00632                   Color color = m_color;
00633                   if ( m_desel ) { // deselected
00634                     color = s_desel_color;
00635                   }
00636                   else {
00637                     m_bin_to_color -> doubleToColor ( val, color );
00638                   }
00639                   m_colorvec.push_back ( color );
00640                   m_colorvec.push_back ( color );
00641 
00642                   // For drawing different contour level with different
00643                   // line style. Use 3 line styles for now.
00644                   if ( m_bin_to_color -> name() == "Line Style" ){
00645                     unsigned int style = ( m_numContours - 1 - k ) % 3;
00646                     Line::Style lineStyle = Line::convert(style);
00647                     m_stylevec.push_back ( lineStyle );
00648                     m_stylevec.push_back ( lineStyle );
00649                   }
00650 
00651                 }
00652               }
00653             }
00654           }
00655         }
00656       }
00657     }
00658   } 
00659 }
00660 
00663 double ContourPointRep::getContour ( int i, const TransformBase * transform  )
00664 {
00665   const BinaryTransform * t 
00666     = dynamic_cast < const BinaryTransform * > ( transform );
00667 
00668   bool zLinear=t->isLinearInZ();
00669   double high=m_maxValue;
00670   double low;
00671 
00672   if (zLinear) {
00673     low = m_minValue;
00674     double width = high - low;
00675     low = low + 0.05 * width;
00676     high = high - 0.05 * width;
00677   }
00678   else{
00679     high = m_maxValue;
00680     low = m_minPos;
00681   }
00682 
00683   t -> transformZ ( high );
00684   t -> transformZ ( low );
00685 
00686   double value = low + ( 
00687                         ( high - low ) * 
00688                 ((double)(i)) /
00689                 ((double)(m_numContours)) 
00690                 );
00691 
00692   t -> inverseTransformZ ( value );
00693 
00694   return value;
00695 
00696 }
00697 
00698 double ContourPointRep::intersect ( int p1, int p2, double * h, double * xh )
00699 {
00700   return (h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1]);
00701 }
00702 
00703 int ContourPointRep::getNumContours() const
00704 {
00705   return m_numContours;
00706 }
00707 
00708 void ContourPointRep::setNumContours ( int i )
00709 {
00710   m_numContours = i;
00711 }
00712 
00713 void ContourPointRep::setUsingUserValues ( bool flag )
00714 {
00715   m_usingUserValues = flag;
00716 }
00717 
00718 bool ContourPointRep::getUsingUserValues () const
00719 {
00720   return m_usingUserValues;
00721 }
00722 
00723 void
00724 ContourPointRep::
00725 setContourValues ( std::vector < double > & values,
00726                    ProjectorBase * proj )
00727 {
00728   
00729   m_usingUserValues = true;
00730   m_numContours = values.size();
00731   m_values.clear();
00732   m_values.reserve ( m_numContours );
00733 
00734   AxisModelBase * a = proj->getAxisModel ( Axes::Z );
00735   assert ( a );
00736   
00737   double sf = a->getScaleFactor();
00738   
00739   vector < double > :: iterator iter = values.begin ();
00740   for ( ; iter != values.end (); iter++ ) {
00741     m_values.push_back ( (*iter)/sf );
00742   }
00743   
00744 }
00745 
00746 void ContourPointRep::setContourVector ( const TransformBase * transform )
00747 {
00748   
00749   if ( m_usingUserValues ) return;
00750   
00751   m_values.clear();
00752   m_values.reserve ( m_numContours );
00753 
00754   for ( int i = 0; i < m_numContours; i++ ){
00755     m_values.push_back ( getContour ( i, transform ) );
00756   }
00757 
00758 }
00759 
00760 void
00761 ContourPointRep::
00762 drawProjectedValues ( const DataSource * ntuple,
00763                       TransformBase * transform,
00764                       ViewBase * view )
00765 {
00766   const BinaryTransform * bt
00767     = dynamic_cast < const BinaryTransform * > ( transform );
00768 
00769   const Range & range = view -> getRange ( Axes::Z );
00770   double high = range.high();
00771   double low = range.low(); //(bt->isLinearInZ())?range.low():range.pos();
00772 
00773   bt -> transformZ ( high );
00774   bt -> transformZ ( low );
00775 
00776   Range newrange ( low, high );
00777 
00778   m_bin_to_color->setRange ( newrange );
00779 
00780   m_x.clear();
00781   m_y.clear();
00782   m_colorvec.clear();
00783 
00784   unsigned int size = ntuple -> rows () * ntuple -> columns ();
00785   m_x.reserve ( size );
00786   m_y.reserve ( size );
00787   m_colorvec.reserve ( size );
00788   
00789   // m_stylevec doesn't work with other color map.
00790   if ( m_bin_to_color -> name() == "Line Style" ){
00791     m_stylevec.clear();
00792     m_stylevec.reserve(size);
00793   }
00794 
00795 
00796   // If periodic transform, process rotation.
00797   bool isPeriodic = bt->isPeriodic();
00798 
00799 
00800   double beta = 0;
00801   double gamma = 0;
00802   double max_x = 0;
00803 
00804   if ( isPeriodic )
00805     { 
00806       const PeriodicBinaryTransform * pbt
00807         = dynamic_cast < const PeriodicBinaryTransform * > ( bt );
00808       
00809       // yOffset is actually doing rotation in X axes.
00810       gamma = pbt -> yOffset ();
00811       beta = pbt -> xOffset();
00812       max_x = pbt -> limitX().high();
00813       // Do rotation
00814       NTuple * newntuple = new NTuple ( ntuple );
00815 
00816       unsigned int rowsize = newntuple -> rows();
00817       unsigned int columnsize = newntuple -> columns();
00818 
00819       for (unsigned int i = 0; i < rowsize; i++) {
00820         const vector < double > & row = newntuple -> getRow (i);
00821         vector <double> newrow;
00822         vector <double> rowdata(columnsize);
00823         
00824         for (unsigned int j=0; j<columnsize; j++) {
00825           rowdata[j]=row[j];
00826         }
00827 
00828         rotate ( rowdata[0], rowdata[1], 0.0, beta,  gamma, (max_x==180));
00829         //bt->transform ( rowdata[0], rowdata[1]);
00830         for (unsigned int j=0; j<columnsize; j++) {
00831           newrow.push_back(rowdata[j]);
00832         }
00833         
00834         newntuple -> replaceRow ( i, newrow );
00835       }
00836     
00837       // Sort the X column of ntuple.
00838       
00839       NTupleSorter * xsorter = new NTupleSorter(newntuple);
00840       xsorter->sort();
00841       NTuple * tempntuple = new NTuple (newntuple);
00842 
00843       // Sort the Y column of ntuple.
00844       const vector < unsigned int > & shape = newntuple -> getShape ();
00845       unsigned int ynum = shape [ 1 ];
00846       unsigned int xnum = shape [ 0 ];
00847 
00848       for (unsigned int i=0; i<xnum; i++){
00849 
00850         tempntuple -> clear();
00851 
00852         for (unsigned int j=0; j<ynum; j++){
00853 
00854           const vector < double > & row = newntuple -> getRow (i*ynum+j);
00855           tempntuple -> insertRow ( j, row );
00856 
00857         }
00858 
00859         NTupleSorter * ysorter = new NTupleSorter(tempntuple);
00860         ysorter -> setSorting(1);
00861         ysorter -> sort();
00862 
00863         for (unsigned int j=0; j<ynum; j++){
00864 
00865           const vector < double > & row2 = tempntuple -> getRow (j);
00866           newntuple -> replaceRow(i*ynum+j, row2);
00867 
00868         }
00869       }
00870 
00871 
00872 
00873       /*  Sort Y column alternative, actully it's not ynum*xnum matrix now.
00874 
00875       tempntuple->clear();
00876       unsigned int ptr=0;
00877       const vector < double > & first = newntuple -> getRow(0);
00878       double tmp=first[0];
00879 
00880       for (unsigned int i=0; i<rowsize; ){
00881         const vector < double > & row = newntuple -> getRow (i);
00882         if (row[0]==tmp){
00883           tempntuple->insertRow(ptr,row);
00884           ptr++;
00885           i++;
00886         }
00887         if (row[0]>tmp) {
00888           //tempntuple->clear();
00889           NTupleSorter * ysorter = new NTupleSorter(tempntuple);
00890           ysorter->setSorting(1);
00891           ysorter->sort();
00892           for (unsigned int j=0; j< ptr-1; j++){
00893             const vector <double> & row2 = tempntuple->getRow(j);
00894             newntuple -> replaceRow(i-ptr+j, row2);
00895           }
00896           tempntuple->clear();
00897           tmp=row[0];
00898           ptr=0;
00899           
00900         }
00901       }
00902         */
00903 
00904 
00905       
00906       setMinMax ( newntuple );
00907       setContourVector ( bt );
00908       createContours ( newntuple, bt );
00909       
00910   }
00911   else
00912   {
00913   // Set the min and max values.
00914   setMinMax ( ntuple );
00915 
00916   // Set the contour values.
00917   setContourVector ( bt );
00918   
00919   // Do the contouring algorithm.
00920     createContours ( ntuple, bt );
00921   // Now you are ready to draw when you get endplot.
00922 
00923   }
00924 
00925   if (m_bin_to_color->name()=="Line Style") {
00926     drawValuesWithStyle( *bt, *view );
00927   } else {
00928     drawValues ( *bt, *view );
00929   }
00930 
00931 }
00932 
00933 void
00934 ContourPointRep::
00935 setMinMax ( const DataSource * ntuple )
00936 {
00937   const vector < double > & values = ntuple -> getColumn ( dp::Z );
00938   Range range ( values );
00939 
00940   m_minValue = range.low ();
00941   m_maxValue = range.high ();
00942   m_minPos = range.pos();
00943 }
00944 
00945 
00946 
00947 
00948 
00949 
00950 void 
00951 ContourPointRep::
00952 rotate ( double & lat, double & lon,
00953          double alpha, double beta, double gamma, bool negative )
00954 {
00955   if (!negative) lat-=180.0;
00956 
00957   // convert to radians from degrees
00958   lat = M_PI * lat / 180.0; 
00959   lon = M_PI * lon / 180.0;
00960   alpha = M_PI * alpha / 180.0;
00961   beta  = M_PI * beta  / 180.0;
00962   gamma = M_PI * gamma / 180.0; 
00963     
00964   // Convert the latitude and longitudes into the cartesian coordinates
00965   // Assume a unit sphere ( Radii does not matter in rotation )
00966   double x = cos( lat ) * cos( lon );
00967   double y = sin( lat ) * cos( lon );
00968   double z = sin( lon );
00969   
00970   // First give a rotation about the x axis ( conventionally denoted by alpha )
00971   double rx =   x;
00972   double ry =   y * cos( alpha ) + z * sin( alpha );
00973   double rz = - y * sin( alpha ) + z * cos( alpha );
00974   
00975   x = rx; y = ry; z = rz;
00976   
00977   // Now give a rotation about the y axis ( conventionally denoted by beta )
00978   rx =   x * cos( beta ) - z * sin( beta );
00979   ry =   y;
00980   rz =   x * sin( beta ) + z * cos( beta );
00981   
00982   x = rx; y = ry; z = rz;
00983   
00984   // Now give a rotation about the z axis ( conventionally denoted by gamma )
00985   rx =   x * cos( gamma ) + y * sin( gamma );
00986   ry = - x * sin( gamma ) + y * cos( gamma );
00987   rz =   z;
00988   
00989   x = rx; y = ry; z = rz;
00990   
00991   // Convert back to latitude and longitudes ( in degrees )
00992   lon = ( 180.0 / M_PI ) * asin( z );
00993   lat = ( 180.0 / M_PI ) * atan2( y, x );
00994 
00995   if (!negative) lat+=180.0;
00996 }

Generated for HippoDraw Class Library by doxygen