ContourPointRep.cxx
Go to the documentation of this file.
1 
11 // For truncation warning
12 #ifdef _MSC_VER
13 #include "msdevstudio/MSconfig.h"
14 #endif
15 
16 #include "ContourPointRep.h"
17 
18 #include "axes/AxisModelBase.h"
19 #include "colorreps/BinToColor.h"
22 #include "datasrcs/NTuple.h"
23 #include "datasrcs/NTupleSorter.h"
24 #include "graphics/DataView.h"
27 
28 #include <cassert>
29 #include <cmath>
30 
31 using namespace hippodraw;
32 
33 using std::max;
34 using std::min;
35 using std::vector;
36 
38  : LinePointRep ( size )
39 {
40  init ();
41 }
42 
44  : LinePointRep ( )
45 {
46  init();
47 }
48 
49 void
51 init ()
52 {
54  m_bin_to_color = factory -> create ( "Rainbow" );
55  m_name = "Contour"; // need to override what base class did
56  m_numContours = 6;
57  m_usingUserValues = false;
58  m_values.clear();
59  m_values.reserve ( m_numContours );
60 }
61 
63  : LinePointRep ( rep )
64 {
65  BinToColor * btc = rep.m_bin_to_color;
66  m_bin_to_color = btc -> clone ();
67 
70  m_values.clear();
71  m_values.reserve ( m_numContours );
72 }
73 
75 {
76  delete m_bin_to_color;
77 }
78 
80 {
81  return new ContourPointRep ( *this );
82 }
83 
84 const BinToColor *
87 {
88  return m_bin_to_color;
89 }
90 
91 void
94 {
95  delete m_bin_to_color;
96  m_bin_to_color = btc;
97 }
98 
100  ViewBase & vb )
101 {
102  // Draw Contour Ticks
103 
104  drawContourTicks ( tf, vb, m_values );
105 
106  // If number of contour level > 20, simply draw segments
107  if (m_numContours>20){
108  try {
109  const BinaryTransform & t
110  = dynamic_cast < const BinaryTransform & > ( tf );
111 
112  t.transform ( m_x, m_y );
113  const Rect & user_rect = vb.getUserRect ();
114  user_rect.makeInBounds ( m_x, m_y );
115 
117 
118  }
119  catch ( ... ) {
120  assert ( false );
121  }
122  }
123 
124  else {
125 
126  // Temporary vectors.
127  vector <double> temp_x;
128  vector <double> temp_y;
129  vector <Line::Style> temp_s;
130 
131  // Current point. ( for line style, only one color used )
132  Color curC=m_colorvec[0];
133  Line::Style curS;
134  double curX, curY;
135 
136  // This flag is set to true when a following segment is found.
137  bool found=false;
138 
139  // Create a vectors for each loop (each contour level may have
140  // more than one loops), and draw the polyline
141  while (!m_x.empty()){
142  temp_x.clear();
143  temp_y.clear();
144  temp_x.push_back(m_x[0]);
145  temp_x.push_back(m_x[1]);
146  temp_y.push_back(m_y[0]);
147  temp_y.push_back(m_y[1]);
148  curX = m_x[1];
149  curY = m_y[1];
150  curS = m_stylevec[1];
151 
152  m_x.erase(m_x.begin(), m_x.begin()+2);
153  m_y.erase(m_y.begin(), m_y.begin()+2);
154  m_stylevec.erase(m_stylevec.begin(), m_stylevec.begin()+2);
155 
156 
157  // Exit the when a loop is formed.
158  while(curX!=temp_x[0] || curY!=temp_y[0]){
159  for (unsigned int i=0; i<m_x.size(); i++) {
160  // A following segment is found.
161  if (m_x[i]==curX && m_y[i]==curY && m_stylevec[i]==curS){
162  found=true;
163  // Add the segment to the current loop
164  if (i%2==0){
165  curX=m_x[i+1];
166  curY=m_y[i+1];
167  temp_x.push_back(curX);
168  temp_y.push_back(curY);
169  m_x.erase(m_x.begin()+i, m_x.begin()+i+2);
170  m_y.erase(m_y.begin()+i, m_y.begin()+i+2);
171  m_stylevec.erase(m_stylevec.begin()+i, m_stylevec.begin()+i+2);
172  } else {
173  curX=m_x[i-1];
174  curY=m_y[i-1];
175  temp_x.push_back(curX);
176  temp_y.push_back(curY);
177  m_x.erase(m_x.begin()+i-1, m_x.begin()+i+1);
178  m_y.erase(m_y.begin()+i-1, m_y.begin()+i+1);
179  m_stylevec.erase(m_stylevec.begin()+i-1, m_stylevec.begin()+i+1);
180  }
181  break;
182  }
183  }
184  // If a following segment cannot be found, break to avoid infinite loop
185  if (found) {found=false; continue;}
186  else break;
187  }
188 
189 
190  // Draw Lines.
191  try {
192  const BinaryTransform & t
193  = dynamic_cast < const BinaryTransform & > ( tf );
194  t.transform (temp_x, temp_y);
195  const Rect & user_rect = vb.getUserRect ();
196  user_rect.makeInBounds (temp_x, temp_y);
197  vb.drawPolyLine(temp_x, temp_y, curS, curC, m_size);
198 
199  }
200  catch ( ... ) {
201  assert ( false );
202  }
203 
204  } // Back to while(!m_x.empty()), draw next polyline.
205 
206  }
207 
208 }
209 
211  ViewBase & vb )
212 {
213  // Draw Contour Ticks
214 
215  drawContourTicks ( tf, vb, m_values );
216 
217  // If number of contour level > 20, simply draw segments
218  if (m_numContours>20){
219  try {
220  const BinaryTransform & t
221  = dynamic_cast < const BinaryTransform & > ( tf );
222 
223  t.transform ( m_x, m_y );
224  const Rect & user_rect = vb.getUserRect ();
225  user_rect.makeInBounds ( m_x, m_y );
226 
228 
229  }
230  catch ( ... ) {
231  assert ( false );
232  }
233  }
234 
235  else {
236 
237  // Temporary vectors.
238  vector <double> temp_x;
239  vector <double> temp_y;
240  vector <Color> temp_c;
241 
242  // Current point.
243  Color curC;
244  double curX, curY;
245 
246  // This flag is set to true when a following segment is found.
247  bool found=false;
248 
249  // Create a vectors for each loop (each contour level may have
250  // more than one loops), and draw the polyline
251  while (!m_x.empty()){
252  temp_x.clear();
253  temp_y.clear();
254  temp_x.push_back(m_x[0]);
255  temp_x.push_back(m_x[1]);
256  temp_y.push_back(m_y[0]);
257  temp_y.push_back(m_y[1]);
258  curX = m_x[1];
259  curY = m_y[1];
260  curC = m_colorvec[1];
261 
262  m_x.erase(m_x.begin(), m_x.begin()+2);
263  m_y.erase(m_y.begin(), m_y.begin()+2);
264  m_colorvec.erase(m_colorvec.begin(), m_colorvec.begin()+2);
265 
266 
267  // Exit the when a loop is formed.
268  while(curX!=temp_x[0] || curY!=temp_y[0]){
269  for (unsigned int i=0; i<m_x.size(); i++) {
270  // A following segment is found.
271  if (m_x[i]==curX && m_y[i]==curY && m_colorvec[i]==curC){
272  found=true;
273  // Add the segment to the current loop
274  if (i%2==0){
275  curX=m_x[i+1];
276  curY=m_y[i+1];
277  temp_x.push_back(curX);
278  temp_y.push_back(curY);
279  m_x.erase(m_x.begin()+i, m_x.begin()+i+2);
280  m_y.erase(m_y.begin()+i, m_y.begin()+i+2);
281  m_colorvec.erase(m_colorvec.begin()+i, m_colorvec.begin()+i+2);
282  } else {
283  curX=m_x[i-1];
284  curY=m_y[i-1];
285  temp_x.push_back(curX);
286  temp_y.push_back(curY);
287  m_x.erase(m_x.begin()+i-1, m_x.begin()+i+1);
288  m_y.erase(m_y.begin()+i-1, m_y.begin()+i+1);
289  m_colorvec.erase(m_colorvec.begin()+i-1, m_colorvec.begin()+i+1);
290  }
291  break;
292  }
293  }
294  // If a following segment cannot be found, break to avoid infinite loop
295  if (found) {found=false; continue;}
296  else break;
297  }
298 
299 
300  // Draw Lines.
301  try {
302  const BinaryTransform & t
303  = dynamic_cast < const BinaryTransform & > ( tf );
304  t.transform (temp_x, temp_y);
305  const Rect & user_rect = vb.getUserRect ();
306  user_rect.makeInBounds (temp_x, temp_y);
307  vb.drawPolyLine(temp_x, temp_y, m_line_style, curC, m_size);
308 
309  }
310  catch ( ... ) {
311  assert ( false );
312  }
313 
314  } // Back to while(!m_x.empty()), draw next polyline.
315 
316  }
317 }
318 
319 
322 void
325  ViewBase & base,
326  const std::vector < double > & values )
327 {
328  vector< double > xv;
329  vector< double > yv;
330 
331  unsigned int size = values.size ();
332  xv.reserve ( size );
333  yv.reserve ( size );
334 
335  DataView & view = dynamic_cast < DataView & > ( base );
336  const Range & range = view.getRange ( Axes::Z );
337 
338  const BinaryTransform & bt
339  = dynamic_cast < const BinaryTransform & > ( tb );
340 
341  const Rect & view_rect = view.getMarginRect ();
342 
343  double tick_length = 6.0;
344  double y_base = view_rect.getY() - 15.0;
345 
346 
347  for ( unsigned int i = 0; i < values.size(); i++ ) {
348 
349  double user_z = values[i];
350 
351  if ( range.excludes ( user_z ) ) continue;
352 
353  bt.transformZ ( user_z );
354 
355  double view_x = view.userToDrawColor ( user_z );
356 
357  xv.push_back ( view_x );
358  yv.push_back ( y_base );
359  xv.push_back ( view_x );
360  yv.push_back ( y_base + tick_length );
361 
362  }
363 
364  view.drawViewLines ( xv, yv, Line::Solid, false, 0 );
365 }
366 
367 namespace dp = hippodraw::DataPoint3DTuple;
368 
369 void
371 createContours ( const DataSource * ntuple,
372  const TransformBase * transform )
373 {
374  int size = m_values.size();
375  assert ( size == m_numContours );
376 
377  if ( ntuple -> rows () == 0 ) return;
378 
379  double h [5];
380  int sh [5];
381  double xh [5];
382  double yh [5];
383  int m1;
384  int m2;
385  int m3;
386  int case_value;
387  double dmin;
388  double dmax;
389  double x1 = 0.0;
390  double x2 = 0.0;
391  double y1 = 0.0;
392  double y2 = 0.0;
393  unsigned int i,j;
394  int k,m;
395 
396  int im[4] = {0,1,1,0};
397  int jm[4] = {0,0,1,1};
398 
399  // Castab = Case Table.
400 
401  // castab[0][0][0] ==> all three points of the triangle are below
402  // the plane of the contour.
403  // 1 ==> in the plane of the contour.
404  // 2 ==> above the plane of the contour.
405 
406  int castab [3][3][3] =
407  {
408  {
409  {0,0,8},{0,2,5},{7,6,9}
410  },
411  {
412  {0,3,4},{1,0,1},{4,3,0}
413  },
414  {
415  {9,6,7},{5,2,0},{8,0,0}
416  }
417  };
418  const vector < unsigned int > & shape = ntuple -> getShape ();
419  unsigned int i_size = shape[0];
420  unsigned int j_size = shape[1];
421  vector < unsigned int > index ( 3 );
422 
423  for ( i = 0; i < i_size - 1; i++ ) {
424 
425  for ( j = 0; j < j_size - 1; j++ ) {
426  // For box given by (i,j), (i,j+1), (i+1,j), (i+1,j+1),
427  // find max and min value.
428 
429  double temp1,temp2;
430  index[0] = i;
431  index[1] = j;
432  index[2] = dp::Z;
433  double tempij = ntuple -> operator [] ( index );
434 
435  index[1] = j+1;
436  double tempij1 = ntuple -> operator [] ( index );
437 
438  temp1 = min ( tempij, tempij1 );
439 
440  index[0] = i+1;
441  index[1] = j;
442  double tempi1j = ntuple -> operator[] ( index );
443 
444  index[1] = j+1;
445  double tempi1j1 = ntuple -> operator [] ( index );
446  temp2 = min ( tempi1j, tempi1j1 );
447 
448  dmin = min ( temp1, temp2 );
449 
450  temp1 = max ( tempij, tempij1 );
451  temp2 = max ( tempi1j, tempi1j1 );
452  dmax = max ( temp1, temp2 );
453 
454  if ( dmax >= m_values [0] &&
455  dmin <= m_values [m_numContours-1] ) {
456 
457  for ( k = 0; k < m_numContours; k++ ) {
458 
459  double curContour = m_values[k];
460 
461  if ( curContour >= dmin &&
462  curContour <= dmax ) {
463 
464  // Contour level k passes through the box.
465 
466  for ( m = 4; m >= 0; m--) {
467 
468  if ( m > 0 ) {
469 
470  index[0] = i + im[m-1];
471  index[1] = j + jm[m-1];
472  index[2] = dp::Z;
473  h[m] = ntuple -> operator [] ( index ) - curContour;
474 
475  index[2] = dp::X;
476  xh[m] = ntuple -> operator [] ( index );
477 
478  index[2] = dp::Y;
479  yh[m] = ntuple -> operator [] ( index );
480 
481  }
482 
483  else {
484 
485  h[0] = 0.25 * ( h[1] + h[2] + h[3] + h[4] );
486  index[0] = i;
487  index[1] = j;
488  index[2] = dp::X;
489  double xij = ntuple -> operator [] ( index );
490 
491  index [0] = i+1;
492  double xi1j = ntuple -> operator [] ( index );
493 
494  index[0] = i;
495  index[1] = j;
496  index[2] = dp::Y;
497  double yij = ntuple -> operator [] ( index );
498 
499  index [1] = j+1;
500  double yij1 = ntuple -> operator [] ( index );
501 
502  xh[0] = 0.50 * ( xij + xi1j );
503  yh[0] = 0.50 * ( yij + yij1 );
504  }
505 
506  if ( h[m] > 0.0 ) {
507  sh[m] = 1;
508  }
509 
510  else if ( h[m] < 0.0 ) {
511  sh[m] = -1;
512  }
513 
514  else {
515  sh[m] = 0;
516  }
517 
518  }
519 
520 // // Note: at this stage the relative heights of the corners and the
521 // // centre are in the h array, and the corresponding coordinates are
522 // // in the xh and yh arrays. The centre of the box is indexed by 0
523 // // and the 4 corners by 1 to 4 as shown below.
524 // // Each triangle is then indexed by the parameter m, and the 3
525 // // vertices of each triangle are indexed by parameters m1,m2,and
526 // // m3.
527 // // It is assumed that the centre of the box is always vertex 2
528 // // though this isimportant only when all 3 vertices lie exactly on
529 // // the same contour level, in which case only the side of the box
530 // // is drawn.
531 // //
532 // //
533 // // vertex 4 +-------------------+ vertex 3
534 // // | \ / |
535 // // | \ m=3 / |
536 // // | \ / |
537 // // | \ / |
538 // // | m=4 0 m=2 | the centre is vertex 0
539 // // | / \ |
540 // // | / \ |
541 // // | / m=1 \ |
542 // // | / \ |
543 // // vertex 1 +-------------------+ vertex 2
544 
545  for (m=1;m<=4;m++) {
546 
547  m1 = m;
548  m2 = 0;
549  if (m!=4) {
550  m3 = m+1;
551  } else {
552  m3 = 1;
553  }
554 
555  case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1];
556 
557  if (case_value!=0) {
558  switch (case_value) {
559  case 1: // Line between vertices 1 and 2
560  x1=xh[m1];
561  y1=yh[m1];
562  x2=xh[m2];
563  y2=yh[m2];
564  break;
565  case 2: // Line between vertices 2 and 3
566  x1=xh[m2];
567  y1=yh[m2];
568  x2=xh[m3];
569  y2=yh[m3];
570  break;
571  case 3: // Line between vertices 3 and 1
572  x1=xh[m3];
573  y1=yh[m3];
574  x2=xh[m1];
575  y2=yh[m1];
576  break;
577  case 4: // Line between vertex 1 and side 2-3
578  x1=xh[m1];
579  y1=yh[m1];
580  x2=intersect(m2,m3,h,xh);
581  y2=intersect(m2,m3,h,yh);
582  break;
583  case 5: // Line between vertex 2 and side 3-1
584  x1=xh[m2];
585  y1=yh[m2];
586  x2=intersect(m3,m1,h,xh);
587  y2=intersect(m3,m1,h,yh);
588  break;
589  case 6: // Line between vertex 3 and side 1-2
590  x1=xh[m3];
591  y1=yh[m3];
592  x2=intersect(m1,m2,h,xh);
593  y2=intersect(m1,m2,h,yh);
594  break;
595  case 7: // Line between sides 1-2 and 2-3
596  x1=intersect(m1,m2,h,xh);
597  y1=intersect(m1,m2,h,yh);
598  x2=intersect(m2,m3,h,xh);
599  y2=intersect(m2,m3,h,yh);
600  break;
601  case 8: // Line between sides 2-3 and 3-1
602  x1=intersect(m2,m3,h,xh);
603  y1=intersect(m2,m3,h,yh);
604  x2=intersect(m3,m1,h,xh);
605  y2=intersect(m3,m1,h,yh);
606  break;
607  case 9: // Line between sides 3-1 and 1-2
608  x1=intersect(m3,m1,h,xh);
609  y1=intersect(m3,m1,h,yh);
610  x2=intersect(m1,m2,h,xh);
611  y2=intersect(m1,m2,h,yh);
612  break;
613  default:
614  break;
615  }
616 
617  const Range r = m_bin_to_color->getRange();
618  double val = curContour;
619 
620  const BinaryTransform * bt
621  = dynamic_cast < const BinaryTransform * > ( transform );
622  bt -> transformZ ( val );
623 
624  if ( ! r.excludes ( val ) ) {
625 
626  m_x.push_back ( x1 );
627  m_x.push_back ( x2 );
628  m_y.push_back ( y1 );
629  m_y.push_back ( y2 );
630 
631  // Pushing twice just to ensure symmetry.
632  Color color = m_color;
633  if ( m_desel ) { // deselected
634  color = s_desel_color;
635  }
636  else {
637  m_bin_to_color -> doubleToColor ( val, color );
638  }
639  m_colorvec.push_back ( color );
640  m_colorvec.push_back ( color );
641 
642  // For drawing different contour level with different
643  // line style. Use 3 line styles for now.
644  if ( m_bin_to_color -> name() == "Line Style" ){
645  unsigned int style = ( m_numContours - 1 - k ) % 3;
646  Line::Style lineStyle = Line::convert(style);
647  m_stylevec.push_back ( lineStyle );
648  m_stylevec.push_back ( lineStyle );
649  }
650 
651  }
652  }
653  }
654  }
655  }
656  }
657  }
658  }
659 }
660 
663 double ContourPointRep::getContour ( int i, const TransformBase * transform )
664 {
665  const BinaryTransform * t
666  = dynamic_cast < const BinaryTransform * > ( transform );
667 
668  bool zLinear=t->isLinearInZ();
669  double high=m_maxValue;
670  double low;
671 
672  if (zLinear) {
673  low = m_minValue;
674  double width = high - low;
675  low = low + 0.05 * width;
676  high = high - 0.05 * width;
677  }
678  else{
679  high = m_maxValue;
680  low = m_minPos;
681  }
682 
683  t -> transformZ ( high );
684  t -> transformZ ( low );
685 
686  double value = low + (
687  ( high - low ) *
688  ((double)(i)) /
689  ((double)(m_numContours))
690  );
691 
692  t -> inverseTransformZ ( value );
693 
694  return value;
695 
696 }
697 
698 double ContourPointRep::intersect ( int p1, int p2, double * h, double * xh )
699 {
700  return (h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1]);
701 }
702 
704 {
705  return m_numContours;
706 }
707 
709 {
710  m_numContours = i;
711 }
712 
714 {
715  m_usingUserValues = flag;
716 }
717 
719 {
720  return m_usingUserValues;
721 }
722 
723 void
725 setContourValues ( std::vector < double > & values,
726  ProjectorBase * proj )
727 {
728 
729  m_usingUserValues = true;
730  m_numContours = values.size();
731  m_values.clear();
732  m_values.reserve ( m_numContours );
733 
734  AxisModelBase * a = proj->getAxisModel ( Axes::Z );
735  assert ( a );
736 
737  double sf = a->getScaleFactor();
738 
739  vector < double > :: iterator iter = values.begin ();
740  for ( ; iter != values.end (); iter++ ) {
741  m_values.push_back ( (*iter)/sf );
742  }
743 
744 }
745 
747 {
748 
749  if ( m_usingUserValues ) return;
750 
751  m_values.clear();
752  m_values.reserve ( m_numContours );
753 
754  for ( int i = 0; i < m_numContours; i++ ){
755  m_values.push_back ( getContour ( i, transform ) );
756  }
757 
758 }
759 
760 void
763  TransformBase * transform,
764  ViewBase * view )
765 {
766  const BinaryTransform * bt
767  = dynamic_cast < const BinaryTransform * > ( transform );
768 
769  const Range & range = view -> getRange ( Axes::Z );
770  double high = range.high();
771  double low = range.low(); //(bt->isLinearInZ())?range.low():range.pos();
772 
773  bt -> transformZ ( high );
774  bt -> transformZ ( low );
775 
776  Range newrange ( low, high );
777 
778  m_bin_to_color->setRange ( newrange );
779 
780  m_x.clear();
781  m_y.clear();
782  m_colorvec.clear();
783 
784  unsigned int size = ntuple -> rows () * ntuple -> columns ();
785  m_x.reserve ( size );
786  m_y.reserve ( size );
787  m_colorvec.reserve ( size );
788 
789  // m_stylevec doesn't work with other color map.
790  if ( m_bin_to_color -> name() == "Line Style" ){
791  m_stylevec.clear();
792  m_stylevec.reserve(size);
793  }
794 
795 
796  // If periodic transform, process rotation.
797  bool isPeriodic = bt->isPeriodic();
798 
799 
800  double beta = 0;
801  double gamma = 0;
802  double max_x = 0;
803 
804  if ( isPeriodic )
805  {
806  const PeriodicBinaryTransform * pbt
807  = dynamic_cast < const PeriodicBinaryTransform * > ( bt );
808 
809  // yOffset is actually doing rotation in X axes.
810  gamma = pbt -> yOffset ();
811  beta = pbt -> xOffset();
812  max_x = pbt -> limitX().high();
813  // Do rotation
814  NTuple * newntuple = new NTuple ( ntuple );
815 
816  unsigned int rowsize = newntuple -> rows();
817  unsigned int columnsize = newntuple -> columns();
818 
819  for (unsigned int i = 0; i < rowsize; i++) {
820  const vector < double > & row = newntuple -> getRow (i);
821  vector <double> newrow;
822  vector <double> rowdata(columnsize);
823 
824  for (unsigned int j=0; j<columnsize; j++) {
825  rowdata[j]=row[j];
826  }
827 
828  rotate ( rowdata[0], rowdata[1], 0.0, beta, gamma, (max_x==180));
829  //bt->transform ( rowdata[0], rowdata[1]);
830  for (unsigned int j=0; j<columnsize; j++) {
831  newrow.push_back(rowdata[j]);
832  }
833 
834  newntuple -> replaceRow ( i, newrow );
835  }
836 
837  // Sort the X column of ntuple.
838 
839  NTupleSorter * xsorter = new NTupleSorter(newntuple);
840  xsorter->sort();
841  NTuple * tempntuple = new NTuple (newntuple);
842 
843  // Sort the Y column of ntuple.
844  const vector < unsigned int > & shape = newntuple -> getShape ();
845  unsigned int ynum = shape [ 1 ];
846  unsigned int xnum = shape [ 0 ];
847 
848  for (unsigned int i=0; i<xnum; i++){
849 
850  tempntuple -> clear();
851 
852  for (unsigned int j=0; j<ynum; j++){
853 
854  const vector < double > & row = newntuple -> getRow (i*ynum+j);
855  tempntuple -> insertRow ( j, row );
856 
857  }
858 
859  NTupleSorter * ysorter = new NTupleSorter(tempntuple);
860  ysorter -> setSorting(1);
861  ysorter -> sort();
862 
863  for (unsigned int j=0; j<ynum; j++){
864 
865  const vector < double > & row2 = tempntuple -> getRow (j);
866  newntuple -> replaceRow(i*ynum+j, row2);
867 
868  }
869  }
870 
871 
872 
873  /* Sort Y column alternative, actully it's not ynum*xnum matrix now.
874 
875  tempntuple->clear();
876  unsigned int ptr=0;
877  const vector < double > & first = newntuple -> getRow(0);
878  double tmp=first[0];
879 
880  for (unsigned int i=0; i<rowsize; ){
881  const vector < double > & row = newntuple -> getRow (i);
882  if (row[0]==tmp){
883  tempntuple->insertRow(ptr,row);
884  ptr++;
885  i++;
886  }
887  if (row[0]>tmp) {
888  //tempntuple->clear();
889  NTupleSorter * ysorter = new NTupleSorter(tempntuple);
890  ysorter->setSorting(1);
891  ysorter->sort();
892  for (unsigned int j=0; j< ptr-1; j++){
893  const vector <double> & row2 = tempntuple->getRow(j);
894  newntuple -> replaceRow(i-ptr+j, row2);
895  }
896  tempntuple->clear();
897  tmp=row[0];
898  ptr=0;
899 
900  }
901  }
902  */
903 
904 
905 
906  setMinMax ( newntuple );
907  setContourVector ( bt );
908  createContours ( newntuple, bt );
909 
910  }
911  else
912  {
913  // Set the min and max values.
914  setMinMax ( ntuple );
915 
916  // Set the contour values.
917  setContourVector ( bt );
918 
919  // Do the contouring algorithm.
920  createContours ( ntuple, bt );
921  // Now you are ready to draw when you get endplot.
922 
923  }
924 
925  if (m_bin_to_color->name()=="Line Style") {
926  drawValuesWithStyle( *bt, *view );
927  } else {
928  drawValues ( *bt, *view );
929  }
930 
931 }
932 
933 void
935 setMinMax ( const DataSource * ntuple )
936 {
937  const vector < double > & values = ntuple -> getColumn ( dp::Z );
938  Range range ( values );
939 
940  m_minValue = range.low ();
941  m_maxValue = range.high ();
942  m_minPos = range.pos();
943 }
944 
945 
946 
947 
948 
949 
950 void
952 rotate ( double & lat, double & lon,
953  double alpha, double beta, double gamma, bool negative )
954 {
955  if (!negative) lat-=180.0;
956 
957  // convert to radians from degrees
958  lat = M_PI * lat / 180.0;
959  lon = M_PI * lon / 180.0;
960  alpha = M_PI * alpha / 180.0;
961  beta = M_PI * beta / 180.0;
962  gamma = M_PI * gamma / 180.0;
963 
964  // Convert the latitude and longitudes into the cartesian coordinates
965  // Assume a unit sphere ( Radii does not matter in rotation )
966  double x = cos( lat ) * cos( lon );
967  double y = sin( lat ) * cos( lon );
968  double z = sin( lon );
969 
970  // First give a rotation about the x axis ( conventionally denoted by alpha )
971  double rx = x;
972  double ry = y * cos( alpha ) + z * sin( alpha );
973  double rz = - y * sin( alpha ) + z * cos( alpha );
974 
975  x = rx; y = ry; z = rz;
976 
977  // Now give a rotation about the y axis ( conventionally denoted by beta )
978  rx = x * cos( beta ) - z * sin( beta );
979  ry = y;
980  rz = x * sin( beta ) + z * cos( beta );
981 
982  x = rx; y = ry; z = rz;
983 
984  // Now give a rotation about the z axis ( conventionally denoted by gamma )
985  rx = x * cos( gamma ) + y * sin( gamma );
986  ry = - x * sin( gamma ) + y * cos( gamma );
987  rz = z;
988 
989  x = rx; y = ry; z = rz;
990 
991  // Convert back to latitude and longitudes ( in degrees )
992  lon = ( 180.0 / M_PI ) * asin( z );
993  lat = ( 180.0 / M_PI ) * atan2( y, x );
994 
995  if (!negative) lat+=180.0;
996 }

Generated for HippoDraw Class Library by doxygen