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 //=============================================================================
45 //
46 // CLASS QtFunctionPlot - IMPLEMENTATION
47 //
48 //=============================================================================
49
50 //== INCLUDES =================================================================
51
52 #ifdef WITH_QWT
53
54 #include "QwtFunctionPlot.hh"
55
56 #include <iostream>
57 #include <algorithm>
58
59 #include <QPen>
60
61 #include <QLineEdit>
62 #include <QLabel>
63 #include <QPainter>
64 #include <qwt_curve_fitter.h>
65 #include <qwt_plot_panner.h>
66 #include <qwt_symbol.h>
67
68
69 #if QWT_VERSION >= 0x060000
70 #include <qwt_plot_histogram.h>
71 #else
72 #include <qwt_interval_data.h>
73 #endif
74
75 #include <cfloat>
76 #include <cmath>
77 #include "TextureMath.hh"
78
79 //== NAMESPACES ===============================================================
80
81 namespace ACG {
82
83 //== IMPLEMENTATION ==========================================================
84
85
87 QwtFunctionPlot::QwtFunctionPlot(QWidget* _parent) :
88 QDialog( _parent ),
89 Ui::QwtFunctionPlotBase(),
90 plot_zoomer_(0),
91 clampMinMarker_(0),
92 minSymbol_(0),
93 clampMaxMarker_(0),
94 maxSymbol_(0),
95 min_(FLT_MAX),
96 max_(FLT_MIN)
97 {
98 setupUi( this );
99
100 plot_zoomer_ = new QwtPlotZoomer( qwtPlot->canvas());
101 plot_zoomer_->initKeyPattern();
102 connect(zoomInButton, SIGNAL( clicked() ), this,SLOT( zoomIn() ) );
103 connect(zoomOutButton,SIGNAL( clicked() ), this,SLOT( zoomOut() ) );
104 connect(clampButton, SIGNAL( clicked() ), this,SLOT( clamp() ) );
105
106 QwtPlotPanner *panner = new QwtPlotPanner( qwtPlot->canvas() );
107 panner->setMouseButton( Qt::MidButton );
108
109 // delete widget on close
110 setAttribute(Qt::WA_DeleteOnClose, true);
111
112 #if QWT_VERSION >= 0x060000
113 histogram_ = new Histogram();
114 #else
115 histogram_ = new HistogramItem();
116 #endif
117
118 image_ = 0;
119 }
120
121 //------------------------------------------------------------------------------
122
123 void QwtFunctionPlot::setFunction( std::vector<double>& _values)
124 {
125 values_ = _values;
126
127 //get min/max values
128 min_ = FLT_MAX;
129 max_ = -FLT_MAX;
130
131 for ( uint i=0; i < values_.size(); i++){
132 min_ = std::min(min_, values_[i] );
133 max_ = std::max(max_, values_[i] );
134 }
135
136 }
137
138 //------------------------------------------------------------------------------
139
140 void QwtFunctionPlot::setParameters(const TexParameters& _parameters)
141 {
142 parameters_ = _parameters;
143 }
144
145 void QwtFunctionPlot::setParameters(
146 bool _repeat,
147 double _repeatMax,
148 bool _clamp,
149 double _clampMin,
150 double _clampMax,
151 bool _center,
152 bool _absolute,
153 bool _scale)
154 {
155
156 parameters_.repeat = _repeat;
157 parameters_.repeatMax = _repeatMax;
158 parameters_.clamp = _clamp;
159 parameters_.clampMin = _clampMin;
160 parameters_.clampMax = _clampMax;
161 parameters_.center = _center;
162 parameters_.abs = _absolute;
163 parameters_.scale = _scale;
164 }
165
166
167 //------------------------------------------------------------------------------
168
169 void QwtFunctionPlot::setImage(QImage* _image)
170 {
171 image_ = _image;
172 }
173
174 //------------------------------------------------------------------------------
175
176 void QwtFunctionPlot::zoomIn()
177 {
178 emit plot_zoomer_->zoom(1);
179 }
180
181 //------------------------------------------------------------------------------
182
183 void QwtFunctionPlot::zoomOut()
184 {
185 emit plot_zoomer_->zoom(-1);
186 }
187
188 //------------------------------------------------------------------------------
189
190 void QwtFunctionPlot::clamp()
191 {
192 QRectF clamped = plot_zoomer_->zoomRect();
193 clamped.setLeft( min_ );
194 clamped.setRight( max_ );
195 emit plot_zoomer_->zoom(clamped);
196 }
197
198 //------------------------------------------------------------------------------
199
200 void QwtFunctionPlot::replot()
201 {
202 //create intervals
203 const int intervalCount = 100;
204
205 #if QWT_VERSION >= 0x060000
206 QVector<QwtIntervalSample> intervals(intervalCount);
207 #else
208 QwtArray<QwtDoubleInterval> intervals(intervalCount);
209 QwtArray<double> count(intervalCount);
210 #endif
211 std::vector< QColor > colors;
212
213 double pos = min_;
214 double width = ( max_ - min_ ) / intervalCount;
215
216 QColor lastColor = Qt::black;
217
218 TextureMath convert(parameters_,min_,max_);
219
220 for ( int i = 0; i < (int)intervals.size(); i++ )
221 {
222
223 #if QWT_VERSION >= 0x060000
224 intervals[i] = QwtIntervalSample(0.0,pos, pos + width);
225 #else
226 intervals[i] = QwtDoubleInterval(pos, pos + width);
227 #endif
228 pos += width;
229
230 //compute a color for the given interval
231 if (image_ != 0){
232
233 const double intervalCenter = pos + (width/2.0);
234
235 const double value = convert.transform(intervalCenter);
236 int val = int( value * ( image_->width() - 1) );
237
238 val = val % image_->width(); // Simulate If texture is repeated, we have to make sure, we stay inside of the image
239 colors.push_back( QColor( image_->pixel(val, 0) ) );
240 lastColor = colors.back();
241 }
242 }
243
244 //sort values into intervals
245 for ( uint i=0; i < values_.size(); i++)
246 for ( int j = 0; j < (int)intervals.size(); j++ )
247 #if QWT_VERSION >= 0x060000
248 if ( intervals[j].interval.contains( values_[i] ) )
249 intervals[j].value++;
250 #else
251 if ( intervals[j].contains( values_[i] ) )
252 count[j]++;
253 #endif
254
255 //get max Count for scaling the y-axis
256 double maxCount = 0;
257
258 for ( int i = 0; i < (int)intervals.size(); i++ )
259 #if QWT_VERSION >= 0x060000
260 maxCount = std::max(maxCount, intervals[i].value);
261 #else
262 maxCount = std::max(maxCount, count[i]);
263 #endif
264
265
266 #if QWT_VERSION >= 0x060000
267 QwtIntervalSeriesData* data = new QwtIntervalSeriesData(intervals);
268 histogram_->setData(data);
269 #else
270 histogram_->setData(QwtIntervalData(intervals, count));
271 #endif
272 histogram_->setColors(colors);
273 histogram_->attach(qwtPlot);
274
275 qwtPlot->setAxisScale(QwtPlot::yLeft, 0.0, maxCount);
276 qwtPlot->setAxisScale(QwtPlot::xBottom, min_, max_);
277
278 qwtPlot->setAxisTitle(QwtPlot::yLeft, "count" );
279 qwtPlot->setAxisTitle(QwtPlot::xBottom, "values" );
280
281 //define this scaling as the zoomBase
282 plot_zoomer_->setZoomBase();
283
284 // Mark the clamp values in the histogramm
285 if ( parameters_.clamp ) {
286 if ( ! clampMinMarker_ ) {
287 clampMinMarker_ = new QwtPlotMarker();
288 minSymbol_ = new QwtSymbol(QwtSymbol::VLine);
289 minSymbol_->setColor(QColor(255,0,0));
290 minSymbol_->setSize(200,1000);
291 QPen pen = minSymbol_->pen();
292 pen.setWidth(3);
293 minSymbol_->setPen(pen);
294 clampMinMarker_->setSymbol(minSymbol_);
295 clampMinMarker_->attach(qwtPlot);
296 }
297
298 // Draw at left boundary if less than the minimal value we get from the function
299 if ( parameters_.clampMin < min_ )
300 clampMinMarker_->setXValue(min_);
301 else
302 clampMinMarker_->setXValue(parameters_.clampMin);
303
304
305
306 clampMinMarker_->show();
307
308 if ( ! clampMaxMarker_ ) {
309 clampMaxMarker_ = new QwtPlotMarker();
310 maxSymbol_ = new QwtSymbol(QwtSymbol::VLine);
311 maxSymbol_->setColor(QColor(0,255,0));
312 maxSymbol_->setSize(200,1000);
313 QPen pen = maxSymbol_->pen();
314 pen.setWidth(3);
315 maxSymbol_->setPen(pen);
316 clampMaxMarker_->setSymbol(maxSymbol_);
317 clampMaxMarker_->attach(qwtPlot);
318 }
319
320 // Draw at right boundary if greater than the maximal value we get from the function
321 if ( parameters_.clampMax < max_ )
322 clampMaxMarker_->setXValue(parameters_.clampMax);
323 else
324 clampMaxMarker_->setXValue(max_);
325
326 clampMaxMarker_->show();
327
328 } else {
329 if ( clampMinMarker_ )
330 clampMinMarker_->hide();
331
332 if ( clampMaxMarker_ )
333 clampMaxMarker_->hide();
334 }
335
336 // an plot it
337 qwtPlot->replot();
338 }
339
340
341
342
343
344 //=============================================================================
345 } // namespace db
346 //=============================================================================
347
348 #endif // WITH_QWT
HistogramItem
Histogram plotting widget.
Definition: HistogramItem.hh:66
TexParameters
Definition: TextureParameters.hh:47
ACG
Namespace providing different geometric functions concerning angles.
Definition: BaseObjectData.hh:68
TextureMath
Definition: TextureMath.hh:49
Histogram
Histogram plot.
Definition: QwtHistogramm.hh:63