Developer Documentation
QwtFunctionPlot.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 //=============================================================================
51 //
52 // CLASS QtFunctionPlot - IMPLEMENTATION
53 //
54 //=============================================================================
55 
56 //== INCLUDES =================================================================
57 
58 #ifdef WITH_QWT
59 
60 #include "QwtFunctionPlot.hh"
61 
62 #include <iostream>
63 #include <algorithm>
64 
65 #include <QPen>
66 
67 #include <QLineEdit>
68 #include <QLabel>
69 #include <QPainter>
70 #include <qwt_curve_fitter.h>
71 #include <qwt_plot_panner.h>
72 #include <qwt_symbol.h>
73 
74 
75 #if QWT_VERSION >= 0x060000
76  #include <qwt_plot_histogram.h>
77 #else
78  #include <qwt_interval_data.h>
79 #endif
80 
81 #include <cfloat>
82 #include <cmath>
83 #include "TextureMath.hh"
84 
85 //== NAMESPACES ===============================================================
86 
87 namespace ACG {
88 
89 //== IMPLEMENTATION ==========================================================
90 
91 
93 QwtFunctionPlot::QwtFunctionPlot(QWidget* _parent) :
94  QDialog( _parent ),
95  Ui::QwtFunctionPlotBase(),
96  plot_zoomer_(0),
97  clampMinMarker_(0),
98  minSymbol_(0),
99  clampMaxMarker_(0),
100  maxSymbol_(0),
101  min_(FLT_MAX),
102  max_(FLT_MIN)
103 {
104  setupUi( this );
105 
106  plot_zoomer_ = new QwtPlotZoomer( qwtPlot->canvas());
107  plot_zoomer_->initKeyPattern();
108  connect(zoomInButton, SIGNAL( clicked() ), this,SLOT( zoomIn() ) );
109  connect(zoomOutButton,SIGNAL( clicked() ), this,SLOT( zoomOut() ) );
110  connect(clampButton, SIGNAL( clicked() ), this,SLOT( clamp() ) );
111 
112  QwtPlotPanner *panner = new QwtPlotPanner( qwtPlot->canvas() );
113  panner->setMouseButton( Qt::MidButton );
114 
115  // delete widget on close
116  setAttribute(Qt::WA_DeleteOnClose, true);
117 
118 #if QWT_VERSION >= 0x060000
119  histogram_ = new Histogram();
120 #else
121  histogram_ = new HistogramItem();
122 #endif
123 
124  image_ = 0;
125 }
126 
127 //------------------------------------------------------------------------------
128 
129 void QwtFunctionPlot::setFunction( std::vector<double>& _values)
130 {
131  values_ = _values;
132 
133  //get min/max values
134  min_ = FLT_MAX;
135  max_ = -FLT_MAX;
136 
137  for ( uint i=0; i < values_.size(); i++){
138  min_ = std::min(min_, values_[i] );
139  max_ = std::max(max_, values_[i] );
140  }
141 
142 }
143 
144 //------------------------------------------------------------------------------
145 
146 void QwtFunctionPlot::setParameters(const TexParameters& _parameters)
147 {
148  parameters_ = _parameters;
149 }
150 
151 void QwtFunctionPlot::setParameters(
152  bool _repeat,
153  double _repeatMax,
154  bool _clamp,
155  double _clampMin,
156  double _clampMax,
157  bool _center,
158  bool _absolute,
159  bool _scale)
160 {
161 
162  parameters_.repeat = _repeat;
163  parameters_.repeatMax = _repeatMax;
164  parameters_.clamp = _clamp;
165  parameters_.clampMin = _clampMin;
166  parameters_.clampMax = _clampMax;
167  parameters_.center = _center;
168  parameters_.abs = _absolute;
169  parameters_.scale = _scale;
170 }
171 
172 
173 //------------------------------------------------------------------------------
174 
175 void QwtFunctionPlot::setImage(QImage* _image)
176 {
177  image_ = _image;
178 }
179 
180 //------------------------------------------------------------------------------
181 
182 void QwtFunctionPlot::zoomIn()
183 {
184  emit plot_zoomer_->zoom(1);
185 }
186 
187 //------------------------------------------------------------------------------
188 
189 void QwtFunctionPlot::zoomOut()
190 {
191  emit plot_zoomer_->zoom(-1);
192 }
193 
194 //------------------------------------------------------------------------------
195 
196 void QwtFunctionPlot::clamp()
197 {
198  QRectF clamped = plot_zoomer_->zoomRect();
199  clamped.setLeft( min_ );
200  clamped.setRight( max_ );
201  emit plot_zoomer_->zoom(clamped);
202 }
203 
204 //------------------------------------------------------------------------------
205 
206 void QwtFunctionPlot::replot()
207 {
208  //create intervals
209  const int intervalCount = 100;
210 
211 #if QWT_VERSION >= 0x060000
212  QVector<QwtIntervalSample> intervals(intervalCount);
213 #else
214  QwtArray<QwtDoubleInterval> intervals(intervalCount);
215  QwtArray<double> count(intervalCount);
216 #endif
217  std::vector< QColor > colors;
218 
219  double pos = min_;
220  double width = ( max_ - min_ ) / intervalCount;
221 
222  QColor lastColor = Qt::black;
223 
224  TextureMath convert(parameters_,min_,max_);
225 
226  for ( int i = 0; i < (int)intervals.size(); i++ )
227  {
228 
229 #if QWT_VERSION >= 0x060000
230  intervals[i] = QwtIntervalSample(0.0,pos, pos + width);
231 #else
232  intervals[i] = QwtDoubleInterval(pos, pos + width);
233 #endif
234  pos += width;
235 
236  //compute a color for the given interval
237  if (image_ != 0){
238 
239  const double intervalCenter = pos + (width/2.0);
240 
241  const double value = convert.transform(intervalCenter);
242  int val = int( value * ( image_->width() - 1) );
243 
244  val = val % image_->width(); // Simulate If texture is repeated, we have to make sure, we stay inside of the image
245  colors.push_back( QColor( image_->pixel(val, 0) ) );
246  lastColor = colors.back();
247  }
248  }
249 
250  //sort values into intervals
251  for ( uint i=0; i < values_.size(); i++)
252  for ( int j = 0; j < (int)intervals.size(); j++ )
253 #if QWT_VERSION >= 0x060000
254  if ( intervals[j].interval.contains( values_[i] ) )
255  intervals[j].value++;
256 #else
257  if ( intervals[j].contains( values_[i] ) )
258  count[j]++;
259 #endif
260 
261  //get max Count for scaling the y-axis
262  double maxCount = 0;
263 
264  for ( int i = 0; i < (int)intervals.size(); i++ )
265 #if QWT_VERSION >= 0x060000
266  maxCount = std::max(maxCount, intervals[i].value);
267 #else
268  maxCount = std::max(maxCount, count[i]);
269 #endif
270 
271 
272 #if QWT_VERSION >= 0x060000
273  QwtIntervalSeriesData* data = new QwtIntervalSeriesData(intervals);
274  histogram_->setData(data);
275 #else
276  histogram_->setData(QwtIntervalData(intervals, count));
277 #endif
278  histogram_->setColors(colors);
279  histogram_->attach(qwtPlot);
280 
281  qwtPlot->setAxisScale(QwtPlot::yLeft, 0.0, maxCount);
282  qwtPlot->setAxisScale(QwtPlot::xBottom, min_, max_);
283 
284  qwtPlot->setAxisTitle(QwtPlot::yLeft, "count" );
285  qwtPlot->setAxisTitle(QwtPlot::xBottom, "values" );
286 
287  //define this scaling as the zoomBase
288  plot_zoomer_->setZoomBase();
289 
290  // Mark the clamp values in the histogramm
291  if ( parameters_.clamp ) {
292  if ( ! clampMinMarker_ ) {
293  clampMinMarker_ = new QwtPlotMarker();
294  minSymbol_ = new QwtSymbol(QwtSymbol::VLine);
295  minSymbol_->setColor(QColor(255,0,0));
296  minSymbol_->setSize(200,1000);
297  QPen pen = minSymbol_->pen();
298  pen.setWidth(3);
299  minSymbol_->setPen(pen);
300  clampMinMarker_->setSymbol(minSymbol_);
301  clampMinMarker_->attach(qwtPlot);
302  }
303 
304  // Draw at left boundary if less than the minimal value we get from the function
305  if ( parameters_.clampMin < min_ )
306  clampMinMarker_->setXValue(min_);
307  else
308  clampMinMarker_->setXValue(parameters_.clampMin);
309 
310 
311 
312  clampMinMarker_->show();
313 
314  if ( ! clampMaxMarker_ ) {
315  clampMaxMarker_ = new QwtPlotMarker();
316  maxSymbol_ = new QwtSymbol(QwtSymbol::VLine);
317  maxSymbol_->setColor(QColor(0,255,0));
318  maxSymbol_->setSize(200,1000);
319  QPen pen = maxSymbol_->pen();
320  pen.setWidth(3);
321  maxSymbol_->setPen(pen);
322  clampMaxMarker_->setSymbol(maxSymbol_);
323  clampMaxMarker_->attach(qwtPlot);
324  }
325 
326  // Draw at right boundary if greater than the maximal value we get from the function
327  if ( parameters_.clampMax < max_ )
328  clampMaxMarker_->setXValue(parameters_.clampMax);
329  else
330  clampMaxMarker_->setXValue(max_);
331 
332  clampMaxMarker_->show();
333 
334  } else {
335  if ( clampMinMarker_ )
336  clampMinMarker_->hide();
337 
338  if ( clampMaxMarker_ )
339  clampMaxMarker_->hide();
340  }
341 
342  // an plot it
343  qwtPlot->replot();
344 }
345 
346 
347 
348 
349 
350 //=============================================================================
351 } // namespace db
352 //=============================================================================
353 
354 #endif // WITH_QWT
Histogram plotting widget.
Histogram plot.
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51