~ubuntu-branches/ubuntu/oneiric/qwt/oneiric-proposed

« back to all changes in this revision

Viewing changes to qwt-5.1.2/examples/bode/bode_plot.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2009-07-01 16:08:21 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090701160821-gog44m4w7x2f4u6o
Tags: 5.2.0-1
* New upstream release.
* Add branch pull patch from svn r544.
* Bump Standards-Version to 3.8.2. No changes needed.
* Update installed manpages.
* Use qwt as base name for directory (drop version).
* Add missing warnings patch.
* Rewrite debian/rules: use dh.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <qwt_math.h>
2
 
#include <qwt_scale_engine.h>
3
 
#include <qwt_symbol.h>
4
 
#include <qwt_plot_grid.h>
5
 
#include <qwt_plot_marker.h>
6
 
#include <qwt_plot_curve.h>
7
 
#include <qwt_legend.h>
8
 
#include <qwt_text.h>
9
 
#include "cplx.h"
10
 
#include "bode_plot.h"
11
 
 
12
 
static void logSpace(double *array, int size, double xmin, double xmax)
13
 
14
 
    if ((xmin <= 0.0) || (xmax <= 0.0) || (size <= 0))
15
 
       return;
16
 
 
17
 
    const int imax = size -1;
18
 
 
19
 
    array[0] = xmin;
20
 
    array[imax] = xmax;
21
 
 
22
 
    const double lxmin = log(xmin);
23
 
    const double lxmax = log(xmax);
24
 
    const double lstep = (lxmax - lxmin) / double(imax);
25
 
 
26
 
    for (int i = 1; i < imax; i++)
27
 
       array[i] = exp(lxmin + double(i) * lstep);
28
 
}
29
 
 
30
 
BodePlot::BodePlot(QWidget *parent):
31
 
    QwtPlot(parent)
32
 
{
33
 
    setAutoReplot(false);
34
 
 
35
 
    setTitle("Frequency Response of a Second-Order System");
36
 
 
37
 
    setCanvasBackground(QColor(Qt::darkBlue));
38
 
 
39
 
    // legend
40
 
    QwtLegend *legend = new QwtLegend;
41
 
    legend->setFrameStyle(QFrame::Box|QFrame::Sunken);
42
 
    insertLegend(legend, QwtPlot::BottomLegend);
43
 
 
44
 
    // grid 
45
 
    QwtPlotGrid *grid = new QwtPlotGrid;
46
 
    grid->enableXMin(true);
47
 
    grid->setMajPen(QPen(Qt::white, 0, Qt::DotLine));
48
 
    grid->setMinPen(QPen(Qt::gray, 0 , Qt::DotLine));
49
 
    grid->attach(this);
50
 
 
51
 
    // axes
52
 
    enableAxis(QwtPlot::yRight);
53
 
    setAxisTitle(QwtPlot::xBottom, "Normalized Frequency");
54
 
    setAxisTitle(QwtPlot::yLeft, "Amplitude [dB]");
55
 
    setAxisTitle(QwtPlot::yRight, "Phase [deg]");
56
 
 
57
 
    setAxisMaxMajor(QwtPlot::xBottom, 6);
58
 
    setAxisMaxMinor(QwtPlot::xBottom, 10);
59
 
    setAxisScaleEngine(QwtPlot::xBottom, new QwtLog10ScaleEngine);
60
 
  
61
 
    // curves
62
 
    d_crv1 = new QwtPlotCurve("Amplitude");
63
 
#if QT_VERSION >= 0x040000
64
 
    d_crv1->setRenderHint(QwtPlotItem::RenderAntialiased);
65
 
#endif
66
 
    d_crv1->setPen(QPen(Qt::yellow));
67
 
    d_crv1->setYAxis(QwtPlot::yLeft);
68
 
    d_crv1->attach(this);
69
 
 
70
 
    d_crv2 = new QwtPlotCurve("Phase");
71
 
#if QT_VERSION >= 0x040000
72
 
    d_crv2->setRenderHint(QwtPlotItem::RenderAntialiased);
73
 
#endif
74
 
    d_crv2->setPen(QPen(Qt::cyan));
75
 
    d_crv2->setYAxis(QwtPlot::yRight);
76
 
    d_crv2->attach(this);
77
 
    
78
 
    // marker
79
 
    d_mrk1 = new QwtPlotMarker();
80
 
    d_mrk1->setValue(0.0, 0.0);
81
 
    d_mrk1->setLineStyle(QwtPlotMarker::VLine);
82
 
    d_mrk1->setLabelAlignment(Qt::AlignRight | Qt::AlignBottom);
83
 
    d_mrk1->setLinePen(QPen(Qt::green, 0, Qt::DashDotLine));
84
 
    d_mrk1->attach(this);
85
 
 
86
 
    d_mrk2 = new QwtPlotMarker();
87
 
    d_mrk2->setLineStyle(QwtPlotMarker::HLine);
88
 
    d_mrk2->setLabelAlignment(Qt::AlignRight | Qt::AlignBottom);
89
 
    d_mrk2->setLinePen(QPen(QColor(200,150,0), 0, Qt::DashDotLine));
90
 
    d_mrk2->setSymbol( QwtSymbol(QwtSymbol::Diamond, 
91
 
        QColor(Qt::yellow), QColor(Qt::green), QSize(7,7)));
92
 
    d_mrk2->attach(this);
93
 
 
94
 
    setDamp(0.0);
95
 
 
96
 
    setAutoReplot(true);
97
 
}
98
 
 
99
 
void BodePlot::showData(double *frequency, double *amplitude,
100
 
    double *phase, int count)
101
 
{
102
 
    d_crv1->setData(frequency, amplitude, count);
103
 
    d_crv2->setData(frequency, phase, count);
104
 
}
105
 
 
106
 
void BodePlot::showPeak(double freq, double amplitude)
107
 
{
108
 
    QString label;
109
 
    label.sprintf("Peak: %.3g dB", amplitude);
110
 
 
111
 
    QwtText text(label);
112
 
    text.setFont(QFont("Helvetica", 10, QFont::Bold));
113
 
    text.setColor(QColor(200,150,0));
114
 
 
115
 
    d_mrk2->setValue(freq, amplitude);
116
 
    d_mrk2->setLabel(text);
117
 
}
118
 
 
119
 
void BodePlot::show3dB(double freq)
120
 
{
121
 
    QString label;
122
 
    label.sprintf("-3 dB at f = %.3g", freq);
123
 
 
124
 
    QwtText text(label);
125
 
    text.setFont(QFont("Helvetica", 10, QFont::Bold));
126
 
    text.setColor(Qt::green);
127
 
 
128
 
    d_mrk1->setValue(freq, 0.0);
129
 
    d_mrk1->setLabel(text);
130
 
}
131
 
 
132
 
//
133
 
// re-calculate frequency response
134
 
//
135
 
void BodePlot::setDamp(double damping)
136
 
{
137
 
    const bool doReplot = autoReplot();
138
 
    setAutoReplot(false);
139
 
 
140
 
    const int ArraySize = 200;
141
 
 
142
 
    double frequency[ArraySize];
143
 
    double amplitude[ArraySize];
144
 
    double phase[ArraySize];
145
 
 
146
 
    // build frequency vector with logarithmic division
147
 
    logSpace(frequency, ArraySize, 0.01, 100);
148
 
 
149
 
    int i3 = 1;
150
 
    double fmax = 1;
151
 
    double amax = -1000.0;
152
 
    
153
 
    for (int i = 0; i < ArraySize; i++)
154
 
    {
155
 
        double f = frequency[i];
156
 
        cplx g = cplx(1.0) / cplx(1.0 - f * f, 2.0 * damping * f);
157
 
        amplitude[i] = 20.0 * log10(sqrt( g.real()*g.real() + g.imag()*g.imag()));
158
 
        phase[i] = atan2(g.imag(), g.real()) * (180.0 / M_PI);
159
 
 
160
 
        if ((i3 <= 1) && (amplitude[i] < -3.0)) 
161
 
           i3 = i;
162
 
        if (amplitude[i] > amax)
163
 
        {
164
 
            amax = amplitude[i];
165
 
            fmax = frequency[i];
166
 
        }
167
 
        
168
 
    }
169
 
    
170
 
    double f3 = frequency[i3] - 
171
 
       (frequency[i3] - frequency[i3 - 1]) 
172
 
          / (amplitude[i3] - amplitude[i3 -1]) * (amplitude[i3] + 3);
173
 
    
174
 
    showPeak(fmax, amax);
175
 
    show3dB(f3);
176
 
    showData(frequency, amplitude, phase, ArraySize);
177
 
 
178
 
    setAutoReplot(doReplot);
179
 
 
180
 
    replot();
181
 
}