ColorBoxPointRep.cxx
Go to the documentation of this file.
1 
12 #ifdef _MSC_VER
13 #include "msdevstudio/MSconfig.h"
14 #endif
15 
16 #include "ColorBoxPointRep.h"
17 
18 #include "colorreps/BinToColor.h"
21 #include "datasrcs/DataSource.h"
22 #include "graphics/ViewBase.h"
24 
25 #include "plotters/PlotterBase.h"
26 
27 
28 #include <cassert>
29 #include <cmath>
30 
31 using namespace hippodraw;
32 
33 using std::vector;
34 
37  : PointRepBase ( "ColorBox", 0.0 )
38 {
40  m_bin_to_color = factory -> create ( "Rainbow" );
41  m_box_edge = false;
42 }
43 
45  : PointRepBase ( point_rep )
46 {
47  BinToColor * btc = point_rep.m_bin_to_color;
48 
49  m_bin_to_color = btc -> clone ();
50  m_box_edge = point_rep.m_box_edge;
51 }
52 
54 {
55  delete m_bin_to_color;
56 }
57 
59 {
60  return new ColorBoxPointRep( *this );
61 }
62 
63 const BinToColor *
66 {
67  return m_bin_to_color;
68 }
69 
70 void
73 {
74  delete m_bin_to_color;
75  m_bin_to_color = btc;
76 }
77 
78 namespace dp = hippodraw::DataPoint3DTuple;
79 
80 void
83  TransformBase * transform,
84  ViewBase * view )
85 {
86  const Range & range = view -> getRange ( Axes::Z );
87  PlotterBase * plotter = view -> getPlotter ();
88 
89  double high = range.high();
90  double low = range.low();
91 
92  const BinaryTransform * bt
93  = dynamic_cast < const BinaryTransform * > ( transform );
94  assert ( bt != 0 );
95 
96  bt -> transformZ ( high );
97  bt -> transformZ ( low );
98 
99  Range newrange ( low, high );
100  m_bin_to_color->setRange ( newrange );
101  const Rect & user_rect = view -> getUserRect ();
102  // Use the rectangle before transform to define box border.
103  const Rect & raw_rect = view -> getRawRect();
104 
105  bool isLinear = bt -> isLinearInXY ();
106  bool surpress_zero = low == 0.0;
107 
108  unsigned int size = ntuple -> rows ();
109 
110  const Color & rep_color = plotter->repColor();
111 
112 
113 
114  // Set rotation parameters.
115  bool isPeriodic = bt -> isPeriodic();
116  double beta=0;
117  double gamma=0;
118  double max_x=0;
119 
120  if ( isPeriodic )
121  {
122  const PeriodicBinaryTransform * pbt
123  = dynamic_cast < const PeriodicBinaryTransform * > ( bt );
124 
125  beta = pbt -> xOffset ();
126  gamma = pbt -> yOffset ();
127  max_x = pbt -> limitX().high();
128  }
129 
130 
131  // keep initialization out of loop.
132 
133  for ( unsigned int i = 0; i < size; i++ ) {
134  const vector < double > & row = ntuple -> getRow ( i );
135 
136  double value = row [ dp::Z ];
137  if ( surpress_zero && value == 0.0 ) continue;
138 
139  double half_xwidth = row [ dp::XERR ];
140  double half_ywidth = row [ dp::YERR ];
141 
142  double x = row [ dp::X ];
143  double y = row [ dp::Y ];
144 
145  // Do rotation before defining box border.
146  // Avoid wrong box size caused by rotation or transform.
147 
148  if ( isPeriodic )
149  {
150  // Rotation should preserve [-180,180] or [0,360] range.
151  rotate ( x, y, 0.0, beta, gamma, (max_x==180) );
152  }
153 
154  // Define box border.
155  double x1 = x - half_xwidth;
156  double y1 = y - half_ywidth;
157  double x2 = x + half_xwidth;
158  double y2 = y + half_ywidth;
159 
160  double xtl = x1;
161  double ytl = y1;
162  double xbl = x1;
163  double ybl = y2;
164  double xtr = x2;
165  double ytr = y1;
166  double xbr = x2;
167  double ybr = y2;
168 
169  raw_rect.makeInBounds ( xtl, ytl );
170  raw_rect.makeInBounds ( xbl, ybl );
171  raw_rect.makeInBounds ( xtr, ytr );
172  raw_rect.makeInBounds ( xbr, ybr );
173 
174  // Do transform after defining box border.
175  if ( isLinear == false ) {
176  bt -> transform ( xtl, ytl );
177  bt -> transform ( xbl, ybl );
178  bt -> transform ( xtr, ytr );
179  bt -> transform ( xbr, ybr );
180  }
181 
182 
183  if ( m_desel ) {
184  if ( isLinear == false ) {
185  std::vector <double> xx;
186  xx.push_back(xtl);
187  xx.push_back(xbl);
188  xx.push_back(xbr);
189  xx.push_back(xtr);
190  std::vector <double> yy;
191  yy.push_back(ytl);
192  yy.push_back(ybl);
193  yy.push_back(ybr);
194  yy.push_back(ytr);
195  Color black(Color::black);
196  view -> drawPolygon ( xx, yy, black, black );
197  } else {
198  const int gray = 256;
199  view -> drawSquare ( x1, y1, x2, y2, gray, gray, gray );
200  }
201  return;
202  }
203 
204 
205  bt -> transformZ ( value );
206 
207  Color color = rep_color;
208 
209  if ( value > user_rect.getZ() ) {
210  if ( !user_rect.isInDepth ( value ) ) {
211  double x(0), y(0);
212  user_rect.makeInBounds(x, y, value);
213  }
214  if ( m_desel ) { // deselected
215  color = s_desel_color;
216  }
217  else {
218  m_bin_to_color -> doubleToColor ( value, color );
219  }
220 
221 
222  if ( isLinear == false ) {
223  /* Draw polygon to fix all periodic transforms */
224  std::vector <double> xx;
225  xx.push_back(xtl);
226  xx.push_back(xbl);
227  xx.push_back(xbr);
228  xx.push_back(xtr);
229  std::vector <double> yy;
230  yy.push_back(ytl);
231  yy.push_back(ybl);
232  yy.push_back(ybr);
233  yy.push_back(ytr);
234  Color black(Color::black);
235  view -> drawPolygon ( xx, yy, color, m_box_edge?black:color );
236 
237  } else {
238  /* Draw square to improve performance
239  Maybe a function that draws the square and the edges at the
240  same time will improve the performance more
241  */
242  view -> drawSquare ( xtl, ytl, xbr, ybr,
243  color.getRed (),
244  color.getGreen(),
245  color.getBlue() );
246  if (m_box_edge) {
247  std::vector<double> x;
248  x.push_back(x1);
249  x.push_back(x2);
250  x.push_back(x2);
251  x.push_back(x1);
252  x.push_back(x1);
253 
254  std::vector<double> y;
255  y.push_back(y1);
256  y.push_back(y1);
257  y.push_back(y2);
258  y.push_back(y2);
259  y.push_back(y1);
260 
262  view->drawPolyLine ( x, y, Line::Solid, color, 1.0 );
263  }
264  }
265  }
266 
267  }
268 }
269 
270 bool
273 {
274  return false;
275 }
276 
277 
278 void
280 rotate ( double & lat, double & lon,
281  double alpha, double beta, double gamma, bool negative )
282 {
283  if ( !negative ) lat-=180.0;
284 
285  // convert to radians from degrees
286  lat = M_PI * lat / 180.0;
287  lon = M_PI * lon / 180.0;
288  alpha = M_PI * alpha / 180.0;
289  beta = M_PI * beta / 180.0;
290  gamma = M_PI * gamma / 180.0;
291 
292  // Convert the latitude and longitudes into the cartesian coordinates
293  // Assume a unit sphere ( Radii does not matter in rotation )
294  double x = cos( lat ) * cos( lon );
295  double y = sin( lat ) * cos( lon );
296  double z = sin( lon );
297 
298  // First give a rotation about the x axis ( conventionally denoted by alpha )
299  double rx = x;
300  double ry = y * cos( alpha ) + z * sin( alpha );
301  double rz = - y * sin( alpha ) + z * cos( alpha );
302 
303  x = rx; y = ry; z = rz;
304 
305  // Now give a rotation about the y axis ( conventionally denoted by beta )
306  rx = x * cos( beta ) - z * sin( beta );
307  ry = y;
308  rz = x * sin( beta ) + z * cos( beta );
309 
310  x = rx; y = ry; z = rz;
311 
312  // Now give a rotation about the z axis ( conventionally denoted by gamma )
313  rx = x * cos( gamma ) + y * sin( gamma );
314  ry = - x * sin( gamma ) + y * cos( gamma );
315  rz = z;
316 
317  x = rx; y = ry; z = rz;
318 
319  // Convert back to latitude and longitudes ( in degrees )
320  lon = ( 180.0 / M_PI ) * asin( z );
321  lat = ( 180.0 / M_PI ) * atan2( y, x );
322 
323  if ( !negative ) lat+=180.0;
324 }
325 
326 
327 void
329 {
330  m_box_edge = show;
331 }

Generated for HippoDraw Class Library by doxygen