QwtFunctionPlot.cc 10.6 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
105
  connect(zoomInButton, SIGNAL( clicked() ), this,SLOT( zoomIn() )  );
  connect(zoomOutButton,SIGNAL( clicked() ), this,SLOT( zoomOut() ) );
  connect(clampButton,  SIGNAL( clicked() ), this,SLOT( clamp() )   );
  
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
}

Dirk Wilden's avatar
Dirk Wilden committed
121
//------------------------------------------------------------------------------
122

Dirk Wilden's avatar
Dirk Wilden committed
123
124
125
void QwtFunctionPlot::setFunction( std::vector<double>& _values)
{
  values_ = _values;
126

Dirk Wilden's avatar
Dirk Wilden committed
127
128
  //get min/max values
  min_ = FLT_MAX;
129
  max_ = -FLT_MAX;
130

Dirk Wilden's avatar
Dirk Wilden committed
131
132
133
  for ( uint i=0; i < values_.size(); i++){
    min_ = std::min(min_, values_[i] );
    max_ = std::max(max_, values_[i] );
134
135
  }

Dirk Wilden's avatar
Dirk Wilden committed
136
}
137

Dirk Wilden's avatar
Dirk Wilden committed
138
//------------------------------------------------------------------------------
139

140
void QwtFunctionPlot::setParameters(const TexParameters& _parameters)
141
{
142
  parameters_ = _parameters;
143
144
}

145
146
147
148
149
150
151
152
153
void QwtFunctionPlot::setParameters(
    bool   _repeat,
    double _repeatMax,
    bool   _clamp,
    double _clampMin,
    double _clampMax,
    bool   _center,
    bool   _absolute,
    bool   _scale)
154
{
155

156
157
158
159
160
161
162
163
  parameters_.repeat    = _repeat;
  parameters_.repeatMax = _repeatMax;
  parameters_.clamp     = _clamp;
  parameters_.clampMin  = _clampMin;
  parameters_.clampMax  = _clampMax;
  parameters_.center    = _center;
  parameters_.abs       = _absolute;
  parameters_.scale     = _scale;
164
165
}

166

Dirk Wilden's avatar
Dirk Wilden committed
167
//------------------------------------------------------------------------------
168

169
void QwtFunctionPlot::setImage(QImage* _image)
Dirk Wilden's avatar
Dirk Wilden committed
170
{
171
  image_ = _image;
Dirk Wilden's avatar
Dirk Wilden committed
172
}
173

Dirk Wilden's avatar
Dirk Wilden committed
174
//------------------------------------------------------------------------------
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
void QwtFunctionPlot::zoomIn()
{
    emit plot_zoomer_->zoom(1);
}

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

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

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

void QwtFunctionPlot::clamp()
{
192
    QRectF clamped = plot_zoomer_->zoomRect();
193
194
    clamped.setLeft( min_ );
    clamped.setRight( max_ );
195
196
197
198
199
    emit plot_zoomer_->zoom(clamped);
}

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

Dirk Wilden's avatar
Dirk Wilden committed
200
void QwtFunctionPlot::replot()
201
{
Dirk Wilden's avatar
Dirk Wilden committed
202
203
  //create intervals
  const int intervalCount = 100;
204

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

213
214
  double pos = min_;
  double width = ( max_ - min_ ) / intervalCount;
Dirk Wilden's avatar
Dirk Wilden committed
215
216
217

  QColor lastColor = Qt::black;

218
219
  TextureMath convert(parameters_,min_,max_);

Dirk Wilden's avatar
Dirk Wilden committed
220
  for ( int i = 0; i < (int)intervals.size(); i++ )
221
  {
222
223
224
225

#if QWT_VERSION >= 0x060000
    intervals[i] = QwtIntervalSample(0.0,pos, pos + width);
#else
Dirk Wilden's avatar
Dirk Wilden committed
226
    intervals[i] = QwtDoubleInterval(pos, pos + width);
227
#endif
Dirk Wilden's avatar
Dirk Wilden committed
228
    pos += width;
229

Dirk Wilden's avatar
Dirk Wilden committed
230
231
    //compute a color for the given interval
    if (image_ != 0){
232

233
      const double intervalCenter = pos + (width/2.0);
234

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

238
      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
239
240
      colors.push_back( QColor( image_->pixel(val, 0) ) );
      lastColor = colors.back();
241
242
    }
  }
Dirk Wilden's avatar
Dirk Wilden committed
243
244
245
246

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

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

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


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

  qwtPlot->setAxisScale(QwtPlot::yLeft, 0.0, maxCount);
276
  qwtPlot->setAxisScale(QwtPlot::xBottom, min_, max_);
Dirk Wilden's avatar
Dirk Wilden committed
277
278
279
280
281
282
283

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

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

284
285
286
287
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
  // 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
336
337
  // an plot it
  qwtPlot->replot();
338
339
340
}


341
342
343



344
345
346
//=============================================================================
} // namespace db
//=============================================================================
347

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