QwtFunctionPlot.cc 10.7 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40
41
\*===========================================================================*/

Jan Möbius's avatar
Jan Möbius committed
42

43

44
45
46
47
48
49
50
51
//=============================================================================
//
//  CLASS QtFunctionPlot - IMPLEMENTATION
//
//=============================================================================

//== INCLUDES =================================================================

Jan Möbius's avatar
Jan Möbius committed
52
#ifdef WITH_QWT
53

54
55
56
57
58
59
60
#include "QwtFunctionPlot.hh"

#include <iostream>
#include <algorithm>

#include <QPen>

61
62
63
#include <QLineEdit>
#include <QLabel>
#include <QPainter>
Dirk Wilden's avatar
Dirk Wilden committed
64
#include <qwt_curve_fitter.h>
65
66
67
#include <qwt_plot_panner.h>
#include <qwt_symbol.h>

Dirk Wilden's avatar
Dirk Wilden committed
68

69
70
71
72
73
#if QWT_VERSION >= 0x060000
 #include <qwt_plot_histogram.h>
#else
 #include <qwt_interval_data.h>
#endif
74

75
76
#include <cfloat>
#include <cmath>
77
#include "TextureMath.hh"
78
79
80
81
82

//== NAMESPACES ===============================================================

namespace ACG {

Jan Möbius's avatar
Jan Möbius committed
83
//== IMPLEMENTATION ==========================================================
84
85


Dirk Wilden's avatar
Dirk Wilden committed
86
/// Default constructor
Jan Möbius's avatar
Jan Möbius committed
87
88
89
QwtFunctionPlot::QwtFunctionPlot(QWidget* _parent) :
    QDialog( _parent ),
    Ui::QwtFunctionPlotBase(),
90
91
92
93
94
    plot_zoomer_(0),
    clampMinMarker_(0),
    minSymbol_(0),
    clampMaxMarker_(0),
    maxSymbol_(0),
Jan Möbius's avatar
Jan Möbius committed
95
96
    min_(FLT_MAX),
    max_(FLT_MIN)
97
{
Dirk Wilden's avatar
Dirk Wilden committed
98
  setupUi( this );
99

Dirk Wilden's avatar
Dirk Wilden committed
100
  plot_zoomer_ = new QwtPlotZoomer( qwtPlot->canvas());
101
  plot_zoomer_->initKeyPattern();
102
103
104
  connect(zoomInButton, SIGNAL( clicked() ), this,SLOT( zoomIn() )  );
  connect(zoomOutButton,SIGNAL( clicked() ), this,SLOT( zoomOut() ) );
  connect(clampButton,  SIGNAL( clicked() ), this,SLOT( clamp() )   );
105

106
107
  QwtPlotPanner *panner = new QwtPlotPanner( qwtPlot->canvas() );
  panner->setMouseButton( Qt::MidButton );
108

Dirk Wilden's avatar
Dirk Wilden committed
109
110
  // delete widget on close
  setAttribute(Qt::WA_DeleteOnClose, true);
111

112
113
114
#if QWT_VERSION >= 0x060000
  histogram_ = new Histogram();
#else
Dirk Wilden's avatar
Dirk Wilden committed
115
  histogram_ = new HistogramItem();
116
117
#endif

Dirk Wilden's avatar
Dirk Wilden committed
118
  image_ = 0;
119
120
}

121
122
123
124
QwtFunctionPlot::~QwtFunctionPlot()
{
  delete histogram_;
}
Dirk Wilden's avatar
Dirk Wilden committed
125
//------------------------------------------------------------------------------
126

Dirk Wilden's avatar
Dirk Wilden committed
127
128
129
void QwtFunctionPlot::setFunction( std::vector<double>& _values)
{
  values_ = _values;
130

Dirk Wilden's avatar
Dirk Wilden committed
131
132
  //get min/max values
  min_ = FLT_MAX;
133
  max_ = -FLT_MAX;
134

Dirk Wilden's avatar
Dirk Wilden committed
135
136
137
  for ( uint i=0; i < values_.size(); i++){
    min_ = std::min(min_, values_[i] );
    max_ = std::max(max_, values_[i] );
138
139
  }

Dirk Wilden's avatar
Dirk Wilden committed
140
}
141

Dirk Wilden's avatar
Dirk Wilden committed
142
//------------------------------------------------------------------------------
143

144
void QwtFunctionPlot::setParameters(const TexParameters& _parameters)
145
{
146
  parameters_ = _parameters;
147
148
}

149
150
151
152
153
154
155
156
157
void QwtFunctionPlot::setParameters(
    bool   _repeat,
    double _repeatMax,
    bool   _clamp,
    double _clampMin,
    double _clampMax,
    bool   _center,
    bool   _absolute,
    bool   _scale)
158
{
159

160
161
162
163
164
165
166
167
  parameters_.repeat    = _repeat;
  parameters_.repeatMax = _repeatMax;
  parameters_.clamp     = _clamp;
  parameters_.clampMin  = _clampMin;
  parameters_.clampMax  = _clampMax;
  parameters_.center    = _center;
  parameters_.abs       = _absolute;
  parameters_.scale     = _scale;
168
169
}

170

Dirk Wilden's avatar
Dirk Wilden committed
171
//------------------------------------------------------------------------------
172

173
void QwtFunctionPlot::setImage(QImage* _image)
Dirk Wilden's avatar
Dirk Wilden committed
174
{
175
  image_ = _image;
Dirk Wilden's avatar
Dirk Wilden committed
176
}
177

Dirk Wilden's avatar
Dirk Wilden committed
178
//------------------------------------------------------------------------------
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
void QwtFunctionPlot::zoomIn()
{
    emit plot_zoomer_->zoom(1);
}

//------------------------------------------------------------------------------

void QwtFunctionPlot::zoomOut()
{
    emit plot_zoomer_->zoom(-1);
}

//------------------------------------------------------------------------------

void QwtFunctionPlot::clamp()
{
196
    QRectF clamped = plot_zoomer_->zoomRect();
197
198
    clamped.setLeft( min_ );
    clamped.setRight( max_ );
199
200
201
202
203
    emit plot_zoomer_->zoom(clamped);
}

//------------------------------------------------------------------------------

Dirk Wilden's avatar
Dirk Wilden committed
204
void QwtFunctionPlot::replot()
205
{
Dirk Wilden's avatar
Dirk Wilden committed
206
207
  //create intervals
  const int intervalCount = 100;
208

209
210
211
#if QWT_VERSION >= 0x060000
  QVector<QwtIntervalSample> intervals(intervalCount);
#else
Dirk Wilden's avatar
Dirk Wilden committed
212
213
  QwtArray<QwtDoubleInterval> intervals(intervalCount);
  QwtArray<double> count(intervalCount);
214
#endif
Dirk Wilden's avatar
Dirk Wilden committed
215
  std::vector< QColor > colors;
216

217
218
  double pos = min_;
  double width = ( max_ - min_ ) / intervalCount;
Dirk Wilden's avatar
Dirk Wilden committed
219
220
221

  QColor lastColor = Qt::black;

222
223
  TextureMath convert(parameters_,min_,max_);

Dirk Wilden's avatar
Dirk Wilden committed
224
  for ( int i = 0; i < (int)intervals.size(); i++ )
225
  {
226
227
228
229

#if QWT_VERSION >= 0x060000
    intervals[i] = QwtIntervalSample(0.0,pos, pos + width);
#else
Dirk Wilden's avatar
Dirk Wilden committed
230
    intervals[i] = QwtDoubleInterval(pos, pos + width);
231
#endif
Dirk Wilden's avatar
Dirk Wilden committed
232
    pos += width;
233

Dirk Wilden's avatar
Dirk Wilden committed
234
235
    //compute a color for the given interval
    if (image_ != 0){
236

237
      const double intervalCenter = pos + (width/2.0);
238

239
240
      const double value = convert.transform(intervalCenter);
      int val = int( value * ( image_->width() - 1) );
Dirk Wilden's avatar
Dirk Wilden committed
241

242
      val = val % image_->width(); // Simulate If texture is repeated, we have to make sure, we stay inside of the image
Dirk Wilden's avatar
Dirk Wilden committed
243
244
      colors.push_back( QColor( image_->pixel(val, 0) ) );
      lastColor = colors.back();
245
246
    }
  }
Dirk Wilden's avatar
Dirk Wilden committed
247
248
249
250

  //sort values into intervals
  for ( uint i=0; i < values_.size(); i++)
    for ( int j = 0; j < (int)intervals.size(); j++ )
251
#if QWT_VERSION >= 0x060000
252
      if ( intervals[j].interval.contains( values_[i]  ) )
253
254
        intervals[j].value++;
#else
255
      if ( intervals[j].contains( values_[i]  ) )
Dirk Wilden's avatar
Dirk Wilden committed
256
        count[j]++;
257
#endif
Dirk Wilden's avatar
Dirk Wilden committed
258
259
260
261
262

  //get max Count for scaling the y-axis
  double maxCount = 0;

  for ( int i = 0; i < (int)intervals.size(); i++ )
263
264
265
#if QWT_VERSION >= 0x060000
    maxCount = std::max(maxCount, intervals[i].value);
#else
Dirk Wilden's avatar
Dirk Wilden committed
266
    maxCount = std::max(maxCount, count[i]);
267
#endif
Dirk Wilden's avatar
Dirk Wilden committed
268
269


270
271
272
273
#if QWT_VERSION >= 0x060000
  QwtIntervalSeriesData* data = new QwtIntervalSeriesData(intervals);
  histogram_->setData(data);
#else
Dirk Wilden's avatar
Dirk Wilden committed
274
  histogram_->setData(QwtIntervalData(intervals, count));
275
#endif
Dirk Wilden's avatar
Dirk Wilden committed
276
277
278
279
  histogram_->setColors(colors);
  histogram_->attach(qwtPlot);

  qwtPlot->setAxisScale(QwtPlot::yLeft, 0.0, maxCount);
280
  qwtPlot->setAxisScale(QwtPlot::xBottom, min_, max_);
Dirk Wilden's avatar
Dirk Wilden committed
281
282
283
284
285
286
287

  qwtPlot->setAxisTitle(QwtPlot::yLeft,   "count" );
  qwtPlot->setAxisTitle(QwtPlot::xBottom, "values" );

  //define this scaling as the zoomBase
  plot_zoomer_->setZoomBase();

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
  // Mark the clamp values in the histogramm
  if ( parameters_.clamp ) {
    if ( ! clampMinMarker_ ) {
      clampMinMarker_ = new QwtPlotMarker();
      minSymbol_ = new QwtSymbol(QwtSymbol::VLine);
      minSymbol_->setColor(QColor(255,0,0));
      minSymbol_->setSize(200,1000);
      QPen pen = minSymbol_->pen();
      pen.setWidth(3);
      minSymbol_->setPen(pen);
      clampMinMarker_->setSymbol(minSymbol_);
      clampMinMarker_->attach(qwtPlot);
    }

    // Draw at left boundary if less than the minimal value we get from the function
    if ( parameters_.clampMin < min_ )
      clampMinMarker_->setXValue(min_);
    else
      clampMinMarker_->setXValue(parameters_.clampMin);



    clampMinMarker_->show();

    if ( ! clampMaxMarker_ ) {
      clampMaxMarker_ = new QwtPlotMarker();
      maxSymbol_ = new QwtSymbol(QwtSymbol::VLine);
      maxSymbol_->setColor(QColor(0,255,0));
      maxSymbol_->setSize(200,1000);
      QPen pen = maxSymbol_->pen();
      pen.setWidth(3);
      maxSymbol_->setPen(pen);
      clampMaxMarker_->setSymbol(maxSymbol_);
      clampMaxMarker_->attach(qwtPlot);
    }

    // Draw at right boundary if greater than the maximal value we get from the function
    if ( parameters_.clampMax < max_ )
      clampMaxMarker_->setXValue(parameters_.clampMax);
    else
      clampMaxMarker_->setXValue(max_);

    clampMaxMarker_->show();

  } else {
    if ( clampMinMarker_ )
      clampMinMarker_->hide();

    if ( clampMaxMarker_ )
      clampMaxMarker_->hide();
  }

Dirk Wilden's avatar
Dirk Wilden committed
340
341
  // an plot it
  qwtPlot->replot();
342
343
344
}


345
346
347



348
349
350
//=============================================================================
} // namespace db
//=============================================================================
351

Jan Möbius's avatar
Jan Möbius committed
352
#endif // WITH_QWT