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
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
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
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
00146
00147
00148 if ( isPeriodic )
00149 {
00150
00151 rotate ( x, y, 0.0, beta, gamma, (max_x==180) );
00152 }
00153
00154
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
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 ) {
00215 color = s_desel_color;
00216 }
00217 else {
00218 m_bin_to_color -> doubleToColor ( value, color );
00219 }
00220
00221
00222 if ( isLinear == false ) {
00223
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
00239
00240
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
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
00293
00294 double x = cos( lat ) * cos( lon );
00295 double y = sin( lat ) * cos( lon );
00296 double z = sin( lon );
00297
00298
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
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
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
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 }