ColorBoxPointRep.cxx

Go to the documentation of this file.
00001 
00012 #ifdef _MSC_VER
00013 #include "msdevstudio/MSconfig.h"
00014 #endif
00015 
00016 #include "ColorBoxPointRep.h"
00017 
00018 #include "colorreps/BinToColor.h"
00019 #include "colorreps/BinToColorFactory.h"
00020 #include "datasrcs/DataPointTuple.h"
00021 #include "datasrcs/DataSource.h"
00022 #include "graphics/ViewBase.h"
00023 #include "transforms/PeriodicBinaryTransform.h"
00024 
00025 #include "plotters/PlotterBase.h"
00026 
00027 
00028 #include <cassert>
00029 #include <cmath>
00030 
00031 using namespace hippodraw;
00032 
00033 using std::vector;
00034 
00035 ColorBoxPointRep::
00036 ColorBoxPointRep ( )
00037   : PointRepBase ( "ColorBox", 0.0 )
00038 {
00039   BinToColorFactory * factory = BinToColorFactory::instance ();
00040   m_bin_to_color = factory -> create ( "Rainbow" );
00041   m_box_edge = false;
00042 }
00043 
00044 ColorBoxPointRep::ColorBoxPointRep ( const ColorBoxPointRep & point_rep )
00045   : PointRepBase ( point_rep )
00046 {
00047   BinToColor * btc = point_rep.m_bin_to_color;
00048 
00049   m_bin_to_color = btc -> clone ();
00050   m_box_edge = point_rep.m_box_edge;
00051 }
00052 
00053 ColorBoxPointRep::~ColorBoxPointRep()
00054 {
00055   delete m_bin_to_color;
00056 }
00057 
00058 RepBase * ColorBoxPointRep::clone()
00059 {
00060   return new ColorBoxPointRep( *this );
00061 }
00062 
00063 const BinToColor *
00064 ColorBoxPointRep::
00065 getValueTransform ( ) const
00066 {
00067   return m_bin_to_color;
00068 }
00069 
00070 void
00071 ColorBoxPointRep::
00072 setValueTransform ( BinToColor * btc )
00073 {
00074   delete m_bin_to_color;
00075   m_bin_to_color = btc;
00076 }
00077 
00078 namespace dp = hippodraw::DataPoint3DTuple;
00079 
00080 void
00081 ColorBoxPointRep::
00082 drawProjectedValues ( const DataSource * ntuple,
00083                       TransformBase * transform,
00084                       ViewBase * view )
00085 {
00086   const Range & range = view -> getRange ( Axes::Z );
00087   PlotterBase * plotter = view -> getPlotter ();
00088 
00089   double high = range.high();
00090   double low = range.low();
00091 
00092   const BinaryTransform * bt
00093     = dynamic_cast < const BinaryTransform * > ( transform );
00094   assert ( bt != 0 );
00095 
00096   bt -> transformZ ( high );
00097   bt -> transformZ ( low );
00098 
00099   Range newrange ( low, high );
00100   m_bin_to_color->setRange ( newrange );
00101   const Rect & user_rect = view -> getUserRect ();
00102   // Use the rectangle before transform to define box border.
00103   const Rect & raw_rect = view -> getRawRect();
00104 
00105   bool isLinear = bt -> isLinearInXY ();
00106   bool surpress_zero = low == 0.0;
00107 
00108   unsigned int size = ntuple -> rows ();
00109 
00110   const Color & rep_color = plotter->repColor();
00111   
00112 
00113 
00114   // Set rotation parameters.
00115   bool isPeriodic = bt -> isPeriodic();
00116   double beta=0;
00117   double gamma=0;
00118   double max_x=0;
00119 
00120   if ( isPeriodic )
00121   {
00122       const PeriodicBinaryTransform * pbt
00123         = dynamic_cast < const PeriodicBinaryTransform * > ( bt );
00124       
00125       beta = pbt -> xOffset ();
00126       gamma = pbt -> yOffset ();
00127       max_x = pbt -> limitX().high();
00128   }
00129 
00130 
00131   // keep initialization out of loop.
00132 
00133   for ( unsigned int i = 0; i < size; i++ ) {
00134     const vector < double > & row = ntuple -> getRow ( i );
00135 
00136     double value = row [ dp::Z ];
00137     if ( surpress_zero && value == 0.0 ) continue;
00138 
00139     double half_xwidth = row [ dp::XERR ];
00140     double half_ywidth = row [ dp::YERR ];
00141 
00142     double x = row [ dp::X ];
00143     double y = row [ dp::Y ];
00144 
00145     // Do rotation before defining box border.    
00146     // Avoid wrong box size caused by rotation or transform.
00147  
00148     if ( isPeriodic )
00149     {    
00150       // Rotation should preserve [-180,180] or [0,360] range.
00151       rotate ( x, y, 0.0, beta, gamma, (max_x==180) );
00152     }
00153 
00154     // Define box border.
00155     double x1 = x - half_xwidth;
00156     double y1 = y - half_ywidth;
00157     double x2 = x + half_xwidth;
00158     double y2 = y + half_ywidth;
00159 
00160     double xtl = x1;
00161     double ytl = y1;
00162     double xbl = x1;
00163     double ybl = y2;
00164     double xtr = x2;
00165     double ytr = y1;
00166     double xbr = x2;
00167     double ybr = y2;
00168 
00169     raw_rect.makeInBounds ( xtl, ytl );
00170     raw_rect.makeInBounds ( xbl, ybl );
00171     raw_rect.makeInBounds ( xtr, ytr );
00172     raw_rect.makeInBounds ( xbr, ybr );
00173      
00174     // Do transform after defining box border.
00175     if ( isLinear == false ) {
00176       bt -> transform ( xtl, ytl );
00177       bt -> transform ( xbl, ybl );
00178       bt -> transform ( xtr, ytr );
00179       bt -> transform ( xbr, ybr );
00180     }
00181 
00182 
00183     if ( m_desel ) {
00184       if ( isLinear == false ) {
00185         std::vector <double> xx;
00186         xx.push_back(xtl);
00187         xx.push_back(xbl);
00188         xx.push_back(xbr);
00189         xx.push_back(xtr);
00190         std::vector <double> yy;
00191         yy.push_back(ytl);
00192         yy.push_back(ybl);
00193         yy.push_back(ybr);
00194         yy.push_back(ytr);
00195         Color black(Color::black);
00196         view -> drawPolygon ( xx, yy, black, black );
00197       } else {
00198         const int gray = 256;
00199         view -> drawSquare ( x1, y1, x2, y2, gray, gray, gray );
00200       }
00201       return;
00202     }
00203      
00204 
00205     bt -> transformZ ( value );
00206 
00207         Color color = rep_color; 
00208 
00209     if ( value > user_rect.getZ() ) {
00210        if ( !user_rect.isInDepth ( value ) ) {
00211           double x(0), y(0);
00212           user_rect.makeInBounds(x, y, value);
00213        }
00214        if ( m_desel ) { // deselected
00215          color = s_desel_color;
00216        }
00217        else { 
00218          m_bin_to_color -> doubleToColor ( value, color );
00219        }
00220 
00221 
00222        if ( isLinear == false ) {
00223          /* Draw polygon to fix all periodic transforms */
00224          std::vector <double> xx;
00225          xx.push_back(xtl);
00226          xx.push_back(xbl);
00227          xx.push_back(xbr);
00228          xx.push_back(xtr);
00229          std::vector <double> yy;
00230          yy.push_back(ytl);
00231          yy.push_back(ybl);
00232          yy.push_back(ybr);
00233          yy.push_back(ytr);
00234          Color black(Color::black);
00235          view -> drawPolygon ( xx, yy, color, m_box_edge?black:color );
00236 
00237        } else {
00238          /* Draw square to improve performance
00239             Maybe a function that draws the square and the edges at the
00240             same time will improve the performance more
00241          */
00242          view -> drawSquare ( xtl, ytl, xbr, ybr,
00243                               color.getRed (), 
00244                               color.getGreen(), 
00245                               color.getBlue() );
00246          if (m_box_edge) {
00247            std::vector<double> x;
00248            x.push_back(x1);
00249            x.push_back(x2);
00250            x.push_back(x2);
00251            x.push_back(x1);
00252            x.push_back(x1);
00253            
00254            std::vector<double> y;
00255            y.push_back(y1);
00256            y.push_back(y1);
00257            y.push_back(y2);
00258            y.push_back(y2);
00259            y.push_back(y1);
00260            
00261            Color color(Color::black);
00262            view->drawPolyLine ( x, y, Line::Solid, color, 1.0 );
00263          }
00264        }
00265     } 
00266 
00267   } 
00268 }
00269 
00270 bool
00271 ColorBoxPointRep::
00272 uses ( Color::Value ) const
00273 {
00274   return false;
00275 }
00276 
00277 
00278 void 
00279 ColorBoxPointRep::
00280 rotate ( double & lat, double & lon,
00281          double alpha, double beta, double gamma, bool negative )
00282 {
00283   if ( !negative ) lat-=180.0;
00284 
00285   // convert to radians from degrees
00286   lat = M_PI * lat / 180.0; 
00287   lon = M_PI * lon / 180.0;
00288   alpha = M_PI * alpha / 180.0;
00289   beta  = M_PI * beta  / 180.0;
00290   gamma = M_PI * gamma / 180.0; 
00291     
00292   // Convert the latitude and longitudes into the cartesian coordinates
00293   // Assume a unit sphere ( Radii does not matter in rotation )
00294   double x = cos( lat ) * cos( lon );
00295   double y = sin( lat ) * cos( lon );
00296   double z = sin( lon );
00297   
00298   // First give a rotation about the x axis ( conventionally denoted by alpha )
00299   double rx =   x;
00300   double ry =   y * cos( alpha ) + z * sin( alpha );
00301   double rz = - y * sin( alpha ) + z * cos( alpha );
00302   
00303   x = rx; y = ry; z = rz;
00304   
00305   // Now give a rotation about the y axis ( conventionally denoted by beta )
00306   rx =   x * cos( beta ) - z * sin( beta );
00307   ry =   y;
00308   rz =   x * sin( beta ) + z * cos( beta );
00309   
00310   x = rx; y = ry; z = rz;
00311   
00312   // Now give a rotation about the z axis ( conventionally denoted by gamma )
00313   rx =   x * cos( gamma ) + y * sin( gamma );
00314   ry = - x * sin( gamma ) + y * cos( gamma );
00315   rz =   z;
00316   
00317   x = rx; y = ry; z = rz;
00318   
00319   // Convert back to latitude and longitudes ( in degrees )
00320   lon = ( 180.0 / M_PI ) * asin( z );
00321   lat = ( 180.0 / M_PI ) * atan2( y, x );
00322   
00323   if ( !negative ) lat+=180.0;
00324 }
00325 
00326 
00327 void 
00328 ColorBoxPointRep::setBoxEdge( bool show )
00329 {
00330   m_box_edge = show;
00331 }

Generated for HippoDraw Class Library by doxygen