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 <qnumeric.h>
13 
15 {
16 public:
17  explicit inline ContourPlane( double z ):
18  d_z( z )
19  {
20  }
21 
22  inline bool intersect( const QwtPoint3D vertex[3],
23  QPointF line[2], bool ignoreOnPlane ) const;
24 
25  inline double z() const { return d_z; }
26 
27 private:
28  inline int compare( double z ) const;
29  inline QPointF intersection(
30  const QwtPoint3D& p1, const QwtPoint3D &p2 ) const;
31 
32  double d_z;
33 };
34 
36  const QwtPoint3D vertex[3], QPointF line[2],
37  bool ignoreOnPlane ) const
38 {
39  bool found = true;
40 
41  // Are the vertices below (-1), on (0) or above (1) the plan ?
42  const int eq1 = compare( vertex[0].z() );
43  const int eq2 = compare( vertex[1].z() );
44  const int eq3 = compare( vertex[2].z() );
45 
46  /*
47  (a) All the vertices lie below the contour level.
48  (b) Two vertices lie below and one on the contour level.
49  (c) Two vertices lie below and one above the contour level.
50  (d) One vertex lies below and two on the contour level.
51  (e) One vertex lies below, one on and one above the contour level.
52  (f) One vertex lies below and two above the contour level.
53  (g) Three vertices lie on the contour level.
54  (h) Two vertices lie on and one above the contour level.
55  (i) One vertex lies on and two above the contour level.
56  (j) All the vertices lie above the contour level.
57  */
58 
59  static const int tab[3][3][3] =
60  {
61  // jump table to avoid nested case statements
62  { { 0, 0, 8 }, { 0, 2, 5 }, { 7, 6, 9 } },
63  { { 0, 3, 4 }, { 1, 10, 1 }, { 4, 3, 0 } },
64  { { 9, 6, 7 }, { 5, 2, 0 }, { 8, 0, 0 } }
65  };
66 
67  const int edgeType = tab[eq1+1][eq2+1][eq3+1];
68  switch ( edgeType )
69  {
70  case 1:
71  // d(0,0,-1), h(0,0,1)
72  line[0] = vertex[0].toPoint();
73  line[1] = vertex[1].toPoint();
74  break;
75  case 2:
76  // d(-1,0,0), h(1,0,0)
77  line[0] = vertex[1].toPoint();
78  line[1] = vertex[2].toPoint();
79  break;
80  case 3:
81  // d(0,-1,0), h(0,1,0)
82  line[0] = vertex[2].toPoint();
83  line[1] = vertex[0].toPoint();
84  break;
85  case 4:
86  // e(0,-1,1), e(0,1,-1)
87  line[0] = vertex[0].toPoint();
88  line[1] = intersection( vertex[1], vertex[2] );
89  break;
90  case 5:
91  // e(-1,0,1), e(1,0,-1)
92  line[0] = vertex[1].toPoint();
93  line[1] = intersection( vertex[2], vertex[0] );
94  break;
95  case 6:
96  // e(-1,1,0), e(1,0,-1)
97  line[0] = vertex[2].toPoint();
98  line[1] = intersection( vertex[0], vertex[1] );
99  break;
100  case 7:
101  // c(-1,1,-1), f(1,1,-1)
102  line[0] = intersection( vertex[0], vertex[1] );
103  line[1] = intersection( vertex[1], vertex[2] );
104  break;
105  case 8:
106  // c(-1,-1,1), f(1,1,-1)
107  line[0] = intersection( vertex[1], vertex[2] );
108  line[1] = intersection( vertex[2], vertex[0] );
109  break;
110  case 9:
111  // f(-1,1,1), c(1,-1,-1)
112  line[0] = intersection( vertex[2], vertex[0] );
113  line[1] = intersection( vertex[0], vertex[1] );
114  break;
115  case 10:
116  // g(0,0,0)
117  // The CONREC algorithm has no satisfying solution for
118  // what to do, when all vertices are on the plane.
119 
120  if ( ignoreOnPlane )
121  found = false;
122  else
123  {
124  line[0] = vertex[2].toPoint();
125  line[1] = vertex[0].toPoint();
126  }
127  break;
128  default:
129  found = false;
130  }
131 
132  return found;
133 }
134 
135 inline int QwtRasterData::ContourPlane::compare( double z ) const
136 {
137  if ( z > d_z )
138  return 1;
139 
140  if ( z < d_z )
141  return -1;
142 
143  return 0;
144 }
145 
147  const QwtPoint3D& p1, const QwtPoint3D &p2 ) const
148 {
149  const double h1 = p1.z() - d_z;
150  const double h2 = p2.z() - d_z;
151 
152  const double x = ( h2 * p1.x() - h1 * p2.x() ) / ( h2 - h1 );
153  const double y = ( h2 * p1.y() - h1 * p2.y() ) / ( h2 - h1 );
154 
155  return QPointF( x, y );
156 }
157 
159 {
160 public:
162 };
163 
166 {
167  d_data = new PrivateData();
168 }
169 
172 {
173  delete d_data;
174 }
175 
183 void QwtRasterData::setAttribute( Attribute attribute, bool on )
184 {
185  if ( on )
186  d_data->attributes |= attribute;
187  else
188  d_data->attributes &= ~attribute;
189 }
190 
196 {
197  return d_data->attributes & attribute;
198 }
199 
215 void QwtRasterData::initRaster( const QRectF &area, const QSize &raster )
216 {
217  Q_UNUSED( area );
218  Q_UNUSED( raster );
219 }
220 
232 {
233 }
234 
261 QRectF QwtRasterData::pixelHint( const QRectF &area ) const
262 {
263  Q_UNUSED( area );
264  return QRectF();
265 }
266 
281  const QRectF &rect, const QSize &raster,
282  const QList<double> &levels, ConrecFlags flags ) const
283 {
285 
286  if ( levels.size() == 0 || !rect.isValid() || !raster.isValid() )
287  return contourLines;
288 
289  const double dx = rect.width() / raster.width();
290  const double dy = rect.height() / raster.height();
291 
292  const bool ignoreOnPlane =
294 
295  const QwtInterval range = interval( Qt::ZAxis );
296  bool ignoreOutOfRange = false;
297  if ( range.isValid() )
298  ignoreOutOfRange = flags & IgnoreOutOfRange;
299 
300  QwtRasterData *that = const_cast<QwtRasterData *>( this );
301  that->initRaster( rect, raster );
302 
303  for ( int y = 0; y < raster.height() - 1; y++ )
304  {
305  enum Position
306  {
307  Center,
308 
309  TopLeft,
310  TopRight,
311  BottomRight,
312  BottomLeft,
313 
314  NumPositions
315  };
316 
317  QwtPoint3D xy[NumPositions];
318 
319  for ( int x = 0; x < raster.width() - 1; x++ )
320  {
321  const QPointF pos( rect.x() + x * dx, rect.y() + y * dy );
322 
323  if ( x == 0 )
324  {
325  xy[TopRight].setX( pos.x() );
326  xy[TopRight].setY( pos.y() );
327  xy[TopRight].setZ(
328  value( xy[TopRight].x(), xy[TopRight].y() )
329  );
330 
331  xy[BottomRight].setX( pos.x() );
332  xy[BottomRight].setY( pos.y() + dy );
333  xy[BottomRight].setZ(
334  value( xy[BottomRight].x(), xy[BottomRight].y() )
335  );
336  }
337 
338  xy[TopLeft] = xy[TopRight];
339  xy[BottomLeft] = xy[BottomRight];
340 
341  xy[TopRight].setX( pos.x() + dx );
342  xy[TopRight].setY( pos.y() );
343  xy[BottomRight].setX( pos.x() + dx );
344  xy[BottomRight].setY( pos.y() + dy );
345 
346  xy[TopRight].setZ(
347  value( xy[TopRight].x(), xy[TopRight].y() )
348  );
349  xy[BottomRight].setZ(
350  value( xy[BottomRight].x(), xy[BottomRight].y() )
351  );
352 
353  double zMin = xy[TopLeft].z();
354  double zMax = zMin;
355  double zSum = zMin;
356 
357  for ( int i = TopRight; i <= BottomLeft; i++ )
358  {
359  const double z = xy[i].z();
360 
361  zSum += z;
362  if ( z < zMin )
363  zMin = z;
364  if ( z > zMax )
365  zMax = z;
366  }
367 
368  if ( qIsNaN( zSum ) )
369  {
370  // one of the points is NaN
371  continue;
372  }
373 
374  if ( ignoreOutOfRange )
375  {
376  if ( !range.contains( zMin ) || !range.contains( zMax ) )
377  continue;
378  }
379 
380  if ( zMax < levels[0] ||
381  zMin > levels[levels.size() - 1] )
382  {
383  continue;
384  }
385 
386  xy[Center].setX( pos.x() + 0.5 * dx );
387  xy[Center].setY( pos.y() + 0.5 * dy );
388  xy[Center].setZ( 0.25 * zSum );
389 
390  const int numLevels = levels.size();
391  for ( int l = 0; l < numLevels; l++ )
392  {
393  const double level = levels[l];
394  if ( level < zMin || level > zMax )
395  continue;
396  QPolygonF &lines = contourLines[level];
397  const ContourPlane plane( level );
398 
399  QPointF line[2];
400  QwtPoint3D vertex[3];
401 
402  for ( int m = TopLeft; m < NumPositions; m++ )
403  {
404  vertex[0] = xy[m];
405  vertex[1] = xy[0];
406  vertex[2] = xy[m != BottomLeft ? m + 1 : TopLeft];
407 
408  const bool intersects =
409  plane.intersect( vertex, line, ignoreOnPlane );
410  if ( intersects )
411  {
412  lines += line[0];
413  lines += line[1];
414  }
415  }
416  }
417  }
418  }
419 
420  that->discardRaster();
421 
422  return contourLines;
423 }
virtual void discardRaster()
Discard a raster.
QPointF toPoint() const
Definition: qwt_point_3d.h:172
void setY(double y)
Sets the y-coordinate of the point to the value specified by y.
Definition: qwt_point_3d.h:158
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:26
Attribute
Raster data attributes.
void setAttribute(Attribute, bool on=true)
double y() const
Definition: qwt_point_3d.h:122
QwtRasterData::Attributes attributes
virtual void initRaster(const QRectF &, const QSize &raster)
Initialize a raster.
TFSIMD_FORCE_INLINE const tfScalar & y() const
Ignore all vertices on the same level.
QMap< double, QPolygonF > ContourLines
Contour lines.
virtual QwtInterval interval(Qt::Axis) const =0
double z() const
Definition: qwt_point_3d.h:128
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:24
bool isValid() const
Definition: qwt_interval.h:211
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:164
TFSIMD_FORCE_INLINE const tfScalar & x() const
double x() const
Definition: qwt_point_3d.h:116
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:152
int i
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 Sat Jul 6 2019 03:44:17