qwt_raster_data.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #include "qwt_raster_data.h"
11 #include "qwt_point_3d.h"
12 #include "qwt_interval.h"
13 
14 #include <qrect.h>
15 #include <qpolygon.h>
16 #include <qnumeric.h>
17 #include <qlist.h>
18 #include <qmap.h>
19 
21 {
22 public:
23  explicit inline ContourPlane( double z ):
24  d_z( z )
25  {
26  }
27 
28  inline bool intersect( const QwtPoint3D vertex[3],
29  QPointF line[2], bool ignoreOnPlane ) const;
30 
31  inline double z() const { return d_z; }
32 
33 private:
34  inline int compare( double z ) const;
35  inline QPointF intersection(
36  const QwtPoint3D& p1, const QwtPoint3D &p2 ) const;
37 
38  double d_z;
39 };
40 
42  const QwtPoint3D vertex[3], QPointF line[2],
43  bool ignoreOnPlane ) const
44 {
45  bool found = true;
46 
47  // Are the vertices below (-1), on (0) or above (1) the plan ?
48  const int eq1 = compare( vertex[0].z() );
49  const int eq2 = compare( vertex[1].z() );
50  const int eq3 = compare( vertex[2].z() );
51 
52  /*
53  (a) All the vertices lie below the contour level.
54  (b) Two vertices lie below and one on the contour level.
55  (c) Two vertices lie below and one above the contour level.
56  (d) One vertex lies below and two on the contour level.
57  (e) One vertex lies below, one on and one above the contour level.
58  (f) One vertex lies below and two above the contour level.
59  (g) Three vertices lie on the contour level.
60  (h) Two vertices lie on and one above the contour level.
61  (i) One vertex lies on and two above the contour level.
62  (j) All the vertices lie above the contour level.
63  */
64 
65  static const int tab[3][3][3] =
66  {
67  // jump table to avoid nested case statements
68  { { 0, 0, 8 }, { 0, 2, 5 }, { 7, 6, 9 } },
69  { { 0, 3, 4 }, { 1, 10, 1 }, { 4, 3, 0 } },
70  { { 9, 6, 7 }, { 5, 2, 0 }, { 8, 0, 0 } }
71  };
72 
73  const int edgeType = tab[eq1+1][eq2+1][eq3+1];
74  switch ( edgeType )
75  {
76  case 1:
77  // d(0,0,-1), h(0,0,1)
78  line[0] = vertex[0].toPoint();
79  line[1] = vertex[1].toPoint();
80  break;
81  case 2:
82  // d(-1,0,0), h(1,0,0)
83  line[0] = vertex[1].toPoint();
84  line[1] = vertex[2].toPoint();
85  break;
86  case 3:
87  // d(0,-1,0), h(0,1,0)
88  line[0] = vertex[2].toPoint();
89  line[1] = vertex[0].toPoint();
90  break;
91  case 4:
92  // e(0,-1,1), e(0,1,-1)
93  line[0] = vertex[0].toPoint();
94  line[1] = intersection( vertex[1], vertex[2] );
95  break;
96  case 5:
97  // e(-1,0,1), e(1,0,-1)
98  line[0] = vertex[1].toPoint();
99  line[1] = intersection( vertex[2], vertex[0] );
100  break;
101  case 6:
102  // e(-1,1,0), e(1,0,-1)
103  line[0] = vertex[2].toPoint();
104  line[1] = intersection( vertex[0], vertex[1] );
105  break;
106  case 7:
107  // c(-1,1,-1), f(1,1,-1)
108  line[0] = intersection( vertex[0], vertex[1] );
109  line[1] = intersection( vertex[1], vertex[2] );
110  break;
111  case 8:
112  // c(-1,-1,1), f(1,1,-1)
113  line[0] = intersection( vertex[1], vertex[2] );
114  line[1] = intersection( vertex[2], vertex[0] );
115  break;
116  case 9:
117  // f(-1,1,1), c(1,-1,-1)
118  line[0] = intersection( vertex[2], vertex[0] );
119  line[1] = intersection( vertex[0], vertex[1] );
120  break;
121  case 10:
122  // g(0,0,0)
123  // The CONREC algorithm has no satisfying solution for
124  // what to do, when all vertices are on the plane.
125 
126  if ( ignoreOnPlane )
127  found = false;
128  else
129  {
130  line[0] = vertex[2].toPoint();
131  line[1] = vertex[0].toPoint();
132  }
133  break;
134  default:
135  found = false;
136  }
137 
138  return found;
139 }
140 
141 inline int QwtRasterData::ContourPlane::compare( double z ) const
142 {
143  if ( z > d_z )
144  return 1;
145 
146  if ( z < d_z )
147  return -1;
148 
149  return 0;
150 }
151 
153  const QwtPoint3D& p1, const QwtPoint3D &p2 ) const
154 {
155  const double h1 = p1.z() - d_z;
156  const double h2 = p2.z() - d_z;
157 
158  const double x = ( h2 * p1.x() - h1 * p2.x() ) / ( h2 - h1 );
159  const double y = ( h2 * p1.y() - h1 * p2.y() ) / ( h2 - h1 );
160 
161  return QPointF( x, y );
162 }
163 
165 {
166 public:
168 };
169 
172 {
173  d_data = new PrivateData();
174 }
175 
178 {
179  delete d_data;
180 }
181 
189 void QwtRasterData::setAttribute( Attribute attribute, bool on )
190 {
191  if ( on )
192  d_data->attributes |= attribute;
193  else
194  d_data->attributes &= ~attribute;
195 }
196 
202 {
203  return d_data->attributes & attribute;
204 }
205 
221 void QwtRasterData::initRaster( const QRectF &area, const QSize &raster )
222 {
223  Q_UNUSED( area );
224  Q_UNUSED( raster );
225 }
226 
238 {
239 }
240 
267 QRectF QwtRasterData::pixelHint( const QRectF &area ) const
268 {
269  Q_UNUSED( area );
270  return QRectF();
271 }
272 
287  const QRectF &rect, const QSize &raster,
288  const QList<double> &levels, ConrecFlags flags ) const
289 {
291 
292  if ( levels.size() == 0 || !rect.isValid() || !raster.isValid() )
293  return contourLines;
294 
295  const double dx = rect.width() / raster.width();
296  const double dy = rect.height() / raster.height();
297 
298  const bool ignoreOnPlane =
300 
301  const QwtInterval range = interval( Qt::ZAxis );
302  bool ignoreOutOfRange = false;
303  if ( range.isValid() )
304  ignoreOutOfRange = flags & IgnoreOutOfRange;
305 
306  QwtRasterData *that = const_cast<QwtRasterData *>( this );
307  that->initRaster( rect, raster );
308 
309  for ( int y = 0; y < raster.height() - 1; y++ )
310  {
311  enum Position
312  {
313  Center,
314 
315  TopLeft,
316  TopRight,
317  BottomRight,
318  BottomLeft,
319 
320  NumPositions
321  };
322 
323  QwtPoint3D xy[NumPositions];
324 
325  for ( int x = 0; x < raster.width() - 1; x++ )
326  {
327  const QPointF pos( rect.x() + x * dx, rect.y() + y * dy );
328 
329  if ( x == 0 )
330  {
331  xy[TopRight].setX( pos.x() );
332  xy[TopRight].setY( pos.y() );
333  xy[TopRight].setZ(
334  value( xy[TopRight].x(), xy[TopRight].y() )
335  );
336 
337  xy[BottomRight].setX( pos.x() );
338  xy[BottomRight].setY( pos.y() + dy );
339  xy[BottomRight].setZ(
340  value( xy[BottomRight].x(), xy[BottomRight].y() )
341  );
342  }
343 
344  xy[TopLeft] = xy[TopRight];
345  xy[BottomLeft] = xy[BottomRight];
346 
347  xy[TopRight].setX( pos.x() + dx );
348  xy[TopRight].setY( pos.y() );
349  xy[BottomRight].setX( pos.x() + dx );
350  xy[BottomRight].setY( pos.y() + dy );
351 
352  xy[TopRight].setZ(
353  value( xy[TopRight].x(), xy[TopRight].y() )
354  );
355  xy[BottomRight].setZ(
356  value( xy[BottomRight].x(), xy[BottomRight].y() )
357  );
358 
359  double zMin = xy[TopLeft].z();
360  double zMax = zMin;
361  double zSum = zMin;
362 
363  for ( int i = TopRight; i <= BottomLeft; i++ )
364  {
365  const double z = xy[i].z();
366 
367  zSum += z;
368  if ( z < zMin )
369  zMin = z;
370  if ( z > zMax )
371  zMax = z;
372  }
373 
374  if ( qIsNaN( zSum ) )
375  {
376  // one of the points is NaN
377  continue;
378  }
379 
380  if ( ignoreOutOfRange )
381  {
382  if ( !range.contains( zMin ) || !range.contains( zMax ) )
383  continue;
384  }
385 
386  if ( zMax < levels[0] ||
387  zMin > levels[levels.size() - 1] )
388  {
389  continue;
390  }
391 
392  xy[Center].setX( pos.x() + 0.5 * dx );
393  xy[Center].setY( pos.y() + 0.5 * dy );
394  xy[Center].setZ( 0.25 * zSum );
395 
396  const int numLevels = levels.size();
397  for ( int l = 0; l < numLevels; l++ )
398  {
399  const double level = levels[l];
400  if ( level < zMin || level > zMax )
401  continue;
402  QPolygonF &lines = contourLines[level];
403  const ContourPlane plane( level );
404 
405  QPointF line[2];
406  QwtPoint3D vertex[3];
407 
408  for ( int m = TopLeft; m < NumPositions; m++ )
409  {
410  vertex[0] = xy[m];
411  vertex[1] = xy[0];
412  vertex[2] = xy[m != BottomLeft ? m + 1 : TopLeft];
413 
414  const bool intersects =
415  plane.intersect( vertex, line, ignoreOnPlane );
416  if ( intersects )
417  {
418  lines += line[0];
419  lines += line[1];
420  }
421  }
422  }
423  }
424  }
425 
426  that->discardRaster();
427 
428  return contourLines;
429 }
virtual void discardRaster()
Discard a raster.
QPointF toPoint() const
Definition: qwt_point_3d.h:157
void setY(double y)
Sets the y-coordinate of the point to the value specified by y.
Definition: qwt_point_3d.h:143
virtual ~QwtRasterData()
Destructor.
virtual QRectF pixelHint(const QRectF &) const
Pixel hint.
int compare(double z) const
bool contains(double value) const
A class representing an interval.
Definition: qwt_interval.h:22
Attribute
Raster data attributes.
void setAttribute(Attribute, bool on=true)
double y() const
Definition: qwt_point_3d.h:107
QwtRasterData::Attributes attributes
virtual void initRaster(const QRectF &, const QSize &raster)
Initialize a raster.
Ignore all vertices on the same level.
virtual QwtInterval interval(Qt::Axis) const =0
double z() const
Definition: qwt_point_3d.h:113
virtual ContourLines contourLines(const QRectF &rect, const QSize &raster, const QList< double > &levels, ConrecFlags) const
QwtPoint3D class defines a 3D point in double coordinates.
Definition: qwt_point_3d.h:21
bool isValid() const
Definition: qwt_interval.h:208
Ignore all values, that are out of range.
void setZ(double y)
Sets the z-coordinate of the point to the value specified by z.
Definition: qwt_point_3d.h:149
double x() const
Definition: qwt_point_3d.h:101
virtual double value(double x, double y) const =0
bool intersect(const QwtPoint3D vertex[3], QPointF line[2], bool ignoreOnPlane) const
QFlags< ConrecFlag > ConrecFlags
Flags to modify the contour algorithm.
bool testAttribute(Attribute) const
QwtRasterData defines an interface to any type of raster data.
QwtRasterData()
Constructor.
void setX(double x)
Sets the x-coordinate of the point to the value specified by x.
Definition: qwt_point_3d.h:137
QPointF intersection(const QwtPoint3D &p1, const QwtPoint3D &p2) const
QFlags< Attribute > Attributes
Raster data Attributes.
PrivateData * d_data


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10