00001
00012
00013 #ifdef _MSC_VER
00014 #include "msdevstudio/MSconfig.h"
00015 #endif
00016
00017 #include "ContourPointRep.h"
00018
00019 #include "BinToColor.h"
00020 #include "BinToColorFactory.h"
00021
00022 #include "axes/AxisModelBase.h"
00023 #include "datasrcs/DataPointTuple.h"
00024 #include "datasrcs/DataSource.h"
00025 #include "graphics/ViewBase.h"
00026 #include "projectors/NTupleProjector.h"
00027 #include "transforms/BinaryTransform.h"
00028
00029 #include <cassert>
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";
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::endPlot ( const TransformBase & tf,
00100 ViewBase & vb,
00101 const Range & range )
00102 {
00103
00104
00105 drawContourTicks ( tf, vb, m_values );
00106
00107
00108
00109 try {
00110 const BinaryTransform & t
00111 = dynamic_cast < const BinaryTransform & > ( tf );
00112
00113 t.transform ( m_x, m_y );
00114 const HippoRectangle & user_rect = vb.getUserRect ();
00115 user_rect.makeInBounds ( m_x, m_y );
00116
00117 vb.drawColorLines ( m_x, m_y, m_line_style, m_colorvec, m_size );
00118
00119 }
00120 catch ( ... ) {
00121 assert ( false );
00122 }
00123 }
00124
00125 void
00126 ContourPointRep::
00127 drawContourTicks ( const TransformBase & tb,
00128 ViewBase & vb,
00129 const std::vector < double > & values )
00130 {
00131
00132 vector< double > xv;
00133 vector< double > yv;
00134
00135 unsigned int size = values.size ();
00136 xv.reserve ( size );
00137 yv.reserve ( size );
00138
00139 const Range & range = vb.getRange ( Axes::Z );
00140
00141 const BinaryTransform & bt
00142 = dynamic_cast < const BinaryTransform & > ( tb );
00143
00144 const HippoRectangle view_rect = vb.getMarginRect ();
00145 double tick_length = 0.05 * view_rect.getHeight ();
00146
00147 double y_base = view_rect.getY() -
00148 ( 1.05 / 9.0 ) * view_rect.getHeight() + 0.05 * view_rect.getHeight();
00149
00150 for ( unsigned int i = 0; i < values.size(); i++ ) {
00151
00152 double user_z = values[i];
00153
00154 if ( range.excludes ( user_z ) ) continue;
00155
00156 bt.transformZ ( user_z );
00157
00158
00159
00160
00161
00162 double view_x = vb.userToDrawColor ( user_z );
00163 xv.push_back ( view_x );
00164 yv.push_back ( y_base );
00165 xv.push_back ( view_x );
00166 yv.push_back ( y_base + tick_length );
00167
00168 }
00169
00170 vb.drawViewLines ( xv, yv, Line::Solid, false, 0 );
00171
00172 }
00173
00174 namespace dp = hippodraw::DataPoint3DTuple;
00175
00176 void
00177 ContourPointRep::
00178 createContours ( const DataSource * ntuple,
00179 const TransformBase * transform )
00180 {
00181 int size = m_values.size();
00182 assert ( size == m_numContours );
00183
00184 if ( ntuple -> rows () == 0 ) return;
00185
00186 double h [5];
00187 int sh [5];
00188 double xh [5];
00189 double yh [5];
00190 int m1;
00191 int m2;
00192 int m3;
00193 int case_value;
00194 double dmin;
00195 double dmax;
00196 double x1 = 0.0;
00197 double x2 = 0.0;
00198 double y1 = 0.0;
00199 double y2 = 0.0;
00200 unsigned int i,j;
00201 int k,m;
00202
00203 int im[4] = {0,1,1,0};
00204 int jm[4] = {0,0,1,1};
00205
00206
00207
00208
00209
00210
00211
00212
00213 int castab [3][3][3] =
00214 {
00215 {
00216 {0,0,8},{0,2,5},{7,6,9}
00217 },
00218 {
00219 {0,3,4},{1,0,1},{4,3,0}
00220 },
00221 {
00222 {9,6,7},{5,2,0},{8,0,0}
00223 }
00224 };
00225 const vector < unsigned int > & shape = ntuple -> getShape ();
00226 unsigned int i_size = shape[0];
00227 unsigned int j_size = shape[1];
00228 vector < unsigned int > index ( 3 );
00229
00230 for ( i = 0; i < i_size - 1; i++ ) {
00231
00232 for ( j = 0; j < j_size - 1; j++ ) {
00233
00234
00235
00236 double temp1,temp2;
00237 index[0] = i;
00238 index[1] = j;
00239 index[2] = dp::Z;
00240 double tempij = ntuple -> operator [] ( index );
00241
00242 index[1] = j+1;
00243 double tempij1 = ntuple -> operator [] ( index );
00244
00245 temp1 = min ( tempij, tempij1 );
00246
00247 index[0] = i+1;
00248 index[1] = j;
00249 double tempi1j = ntuple -> operator[] ( index );
00250
00251 index[1] = j+1;
00252 double tempi1j1 = ntuple -> operator [] ( index );
00253 temp2 = min ( tempi1j, tempi1j1 );
00254
00255 dmin = min ( temp1, temp2 );
00256
00257 temp1 = max ( tempij, tempij1 );
00258 temp2 = max ( tempi1j, tempi1j1 );
00259 dmax = max ( temp1, temp2 );
00260
00261 if ( dmax >= m_values [0] &&
00262 dmin <= m_values [m_numContours-1] ) {
00263
00264 for ( k = 0; k < m_numContours; k++ ) {
00265
00266 double curContour = m_values[k];
00267
00268 if ( curContour >= dmin &&
00269 curContour <= dmax ) {
00270
00271
00272
00273 for ( m = 4; m >= 0; m--) {
00274
00275 if ( m > 0 ) {
00276
00277 index[0] = i + im[m-1];
00278 index[1] = j + jm[m-1];
00279 index[2] = dp::Z;
00280 h[m] = ntuple -> operator [] ( index ) - curContour;
00281
00282 index[2] = dp::X;
00283 xh[m] = ntuple -> operator [] ( index );
00284
00285 index[2] = dp::Y;
00286 yh[m] = ntuple -> operator [] ( index );
00287
00288 }
00289
00290 else {
00291
00292 h[0] = 0.25 * ( h[1] + h[2] + h[3] + h[4] );
00293 index[0] = i;
00294 index[1] = j;
00295 index[2] = dp::X;
00296 double xij = ntuple -> operator [] ( index );
00297
00298 index [0] = i+1;
00299 double xi1j = ntuple -> operator [] ( index );
00300
00301 index[0] = i;
00302 index[1] = j;
00303 index[2] = dp::Y;
00304 double yij = ntuple -> operator [] ( index );
00305
00306 index [1] = j+1;
00307 double yij1 = ntuple -> operator [] ( index );
00308
00309 xh[0] = 0.50 * ( xij + xi1j );
00310 yh[0] = 0.50 * ( yij + yij1 );
00311 }
00312
00313 if ( h[m] > 0.0 ) {
00314 sh[m] = 1;
00315 }
00316
00317 else if ( h[m] < 0.0 ) {
00318 sh[m] = -1;
00319 }
00320
00321 else {
00322 sh[m] = 0;
00323 }
00324
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 for (m=1;m<=4;m++) {
00353
00354 m1 = m;
00355 m2 = 0;
00356 if (m!=4) {
00357 m3 = m+1;
00358 } else {
00359 m3 = 1;
00360 }
00361
00362 case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1];
00363
00364 if (case_value!=0) {
00365 switch (case_value) {
00366 case 1:
00367 x1=xh[m1];
00368 y1=yh[m1];
00369 x2=xh[m2];
00370 y2=yh[m2];
00371 break;
00372 case 2:
00373 x1=xh[m2];
00374 y1=yh[m2];
00375 x2=xh[m3];
00376 y2=yh[m3];
00377 break;
00378 case 3:
00379 x1=xh[m3];
00380 y1=yh[m3];
00381 x2=xh[m1];
00382 y2=yh[m1];
00383 break;
00384 case 4:
00385 x1=xh[m1];
00386 y1=yh[m1];
00387 x2=intersect(m2,m3,h,xh);
00388 y2=intersect(m2,m3,h,yh);
00389 break;
00390 case 5:
00391 x1=xh[m2];
00392 y1=yh[m2];
00393 x2=intersect(m3,m1,h,xh);
00394 y2=intersect(m3,m1,h,yh);
00395 break;
00396 case 6:
00397 x1=xh[m3];
00398 y1=yh[m3];
00399 x2=intersect(m1,m2,h,xh);
00400 y2=intersect(m1,m2,h,yh);
00401 break;
00402 case 7:
00403 x1=intersect(m1,m2,h,xh);
00404 y1=intersect(m1,m2,h,yh);
00405 x2=intersect(m2,m3,h,xh);
00406 y2=intersect(m2,m3,h,yh);
00407 break;
00408 case 8:
00409 x1=intersect(m2,m3,h,xh);
00410 y1=intersect(m2,m3,h,yh);
00411 x2=intersect(m3,m1,h,xh);
00412 y2=intersect(m3,m1,h,yh);
00413 break;
00414 case 9:
00415 x1=intersect(m3,m1,h,xh);
00416 y1=intersect(m3,m1,h,yh);
00417 x2=intersect(m1,m2,h,xh);
00418 y2=intersect(m1,m2,h,yh);
00419 break;
00420 default:
00421 break;
00422 }
00423
00424 const Range & r = m_bin_to_color->getRange();
00425 double val = curContour;
00426
00427 const BinaryTransform * bt
00428 = dynamic_cast < const BinaryTransform * > ( transform );
00429 bt -> transformZ ( val );
00430
00431 if ( ! r.excludes ( val ) ) {
00432
00433 m_x.push_back ( x1 );
00434 m_x.push_back ( x2 );
00435 m_y.push_back ( y1 );
00436 m_y.push_back ( y2 );
00437
00438
00439 Color color;
00440 m_bin_to_color -> doubleToColor ( val, color );
00441 m_colorvec.push_back ( color );
00442 m_colorvec.push_back ( color );
00443 }
00444 }
00445 }
00446 }
00447 }
00448 }
00449 }
00450 }
00451 }
00452
00455 double ContourPointRep::getContour ( int i, const TransformBase * transform )
00456 {
00457 double high = m_maxValue;
00458 double low = m_minValue;
00459
00460 double width = high - low;
00461 low = low + 0.05 * width;
00462 high = high - 0.05 * width;
00463
00464
00465
00466 const BinaryTransform * t
00467 = dynamic_cast < const BinaryTransform * > ( transform );
00468
00469 t -> transformZ ( high );
00470 t -> transformZ ( low );
00471
00472 double value = low + (
00473 ( high - low ) *
00474 ((double)(i)) /
00475 ((double)(m_numContours))
00476 );
00477
00478 t -> inverseTransformZ ( value );
00479
00480 return value;
00481
00482 }
00483
00484 double ContourPointRep::intersect ( int p1, int p2, double * h, double * xh )
00485 {
00486 return (h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1]);
00487 }
00488
00489 int ContourPointRep::getNumContours() const
00490 {
00491 return m_numContours;
00492 }
00493
00494 void ContourPointRep::setNumContours ( int i )
00495 {
00496 m_numContours = i;
00497 }
00498
00499 void ContourPointRep::setUsingUserValues ( bool flag )
00500 {
00501 m_usingUserValues = flag;
00502 }
00503
00504 bool ContourPointRep::getUsingUserValues () const
00505 {
00506 return m_usingUserValues;
00507 }
00508
00509 void
00510 ContourPointRep::
00511 setContourValues ( std::vector < double > & values,
00512 ProjectorBase * proj )
00513 {
00514
00515 m_usingUserValues = true;
00516 m_numContours = values.size();
00517 m_values.clear();
00518 m_values.reserve ( m_numContours );
00519
00520 AxisModelBase * a = proj->getAxisModel ( Axes::Z );
00521 assert ( a );
00522
00523 double sf = a->getScaleFactor();
00524
00525 vector < double > :: iterator iter = values.begin ();
00526 for ( ; iter != values.end (); iter++ ) {
00527 m_values.push_back ( (*iter)/sf );
00528 }
00529
00530 }
00531
00532 void ContourPointRep::setContourVector ( const TransformBase * transform )
00533 {
00534
00535 if ( m_usingUserValues ) return;
00536
00537 m_values.clear();
00538 m_values.reserve ( m_numContours );
00539
00540 for ( int i = 0; i < m_numContours; i++ ){
00541 m_values.push_back ( getContour ( i, transform ) );
00542 }
00543
00544 }
00545
00546 void
00547 ContourPointRep::
00548 drawProjectedValues ( const DataSource * ntuple,
00549 TransformBase * transform,
00550 ViewBase * view )
00551 {
00552 const Range & range = view -> getRange ( Axes::Z );
00553 double high = range.high();
00554 double low = range.low();
00555
00556 const BinaryTransform * bt
00557 = dynamic_cast < const BinaryTransform * > ( transform );
00558
00559 bt -> transformZ ( high );
00560 bt -> transformZ ( low );
00561
00562 Range newrange ( low, high );
00563
00564 m_bin_to_color->setRange ( newrange );
00565
00566 m_x.clear();
00567 m_y.clear();
00568 m_colorvec.clear();
00569
00570 unsigned int size = ntuple -> rows () * ntuple -> columns ();
00571 m_x.reserve ( size );
00572 m_y.reserve ( size );
00573 m_colorvec.reserve ( size );
00574
00575
00576 setMinMax ( ntuple );
00577
00578
00579 setContourVector ( bt );
00580
00581
00582 createContours ( ntuple, bt );
00583
00584
00585 endPlot ( *bt, *view, newrange );
00586
00587 }
00588
00589 void
00590 ContourPointRep::
00591 setMinMax ( const DataSource * ntuple )
00592 {
00593 const vector < double > & values = ntuple -> getColumn ( dp::Z );
00594 Range range ( values );
00595
00596 m_minValue = range.low ();
00597 m_maxValue = range.high ();
00598 }