1
2
3
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
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
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
|
//============================================================================
//
// KPendulum screen saver for KDE
// $Id$
// Copyright (C) 2004 Georg Drenkhahn
//
// This file is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 2 as published by the
// Free Software Foundation.
//
//============================================================================
#ifndef __PENDULUM_H__
#define __PENDULUM_H__
// STL headers
#include <valarray>
// Qt headers
#include <qwidget.h>
#include <qtimer.h>
#include <qgl.h>
// GL headers
#include <GL/glu.h>
#include <GL/gl.h>
// KDE headers
#include <kscreensaver.h>
#include "vec3.h"
#include "rkodesolver.h"
// KPendulumSetupUi
#include "pendulumcfg.h"
//--------------------------------------------------------------------
/** @brief ODE solver for the Pendulum equations */
class PendulumOdeSolver : public RkOdeSolver<double>
{
public:
/** @brief Constuctor for the RK solver of the pendulum equation of motion
* @param t initial time in seconds
* @param dt initial time increment in seconds, just a hint for solver
* @param y generalized coordinates of pendulum system
* @param eps relative precision
* @param m1 mass of upper pendulum
* @param m2 mass of lower pendulum
* @param l1 length of upper pendulum
* @param l2 length of lower pendulum
* @param g gravitational constant */
PendulumOdeSolver(
const double &t,
const double &dt,
std::valarray<double> &y,
const double &eps,
const double &m1,
const double &m2,
const double &l1,
const double &l2,
const double &g
);
protected:
/** @brief ODE function for the pendulum equation of motion system
* @param x time
* @param y generalized coordinates of pendulum system
* @return derivation dy/dx */
std::valarray<double>
f(const double &x, const std::valarray<double> &y) const;
private:
/** These private variables contain constants for faster numeric calculation.
* They are derived from the constructor arguments m1,m2,l1,l2,g. */
const double A, B1, B, C, D, E, M;
};
//--------------------------------------------------------------------
/** @brief GL widget class for the KPendulum screen saver
*
* Class implements QGLWidget to display the KPendulum screen saver. */
class PendulumGLWidget : public QGLWidget
{
Q_OBJECT
public:
/** @brief Constructor of KPendulum's GL widget
* @param parent parent widget, passed to QGLWidget's constructor
* @param name name of widget, passed to QGLWidget's constructor */
PendulumGLWidget(QWidget* parent=0, const char* name=0);
/** @brief Destructor of KPendulum's GL widget */
~PendulumGLWidget(void);
/** @brief Set phi angle of viewpoint
* @param phi angle in sterad */
void setEyePhi(double phi);
/** @brief Set angles of pendulum configuration
* @param q1 angle of 1. pendulum in sterad
* @param q2 angle of 2. pendulum in sterad */
void setAngles(const double& q1, const double& q2);
/** @brief Set masses of pendulum configuration
* @param m1 mass of 1. pendulum
* @param m2 mass of 2. pendulum */
void setMasses(const double& m1, const double& m2);
/** @brief Set lengths of pendulum configuration
* @param l1 length of 1. pendulum
* @param l2 length of 2. pendulum */
void setLengths(const double& l1, const double& l2);
/* accessors for colour settings */
/** @brief set color of the bars
* @param c color */
void setBarColor(const QColor& c);
/** @brief get color of the bars
* @return color */
inline QColor barColor(void) const {return m_barColor;}
/** @brief set color of mass 1
* @param c color */
void setM1Color(const QColor& c);
/** @brief get color of mass 1
* @return color */
inline QColor m1Color(void) const {return m_m1Color;}
/** @brief set color of mass 2
* @param c color */
void setM2Color(const QColor& c);
/** @brief get color of mass 2
* @return color */
inline QColor m2Color(void) const {return m_m2Color;}
protected:
/** paint the GL view */
virtual void paintGL();
/** resize the gl view */
virtual void resizeGL(int w, int h);
/** setup the GL enviroment */
virtual void initializeGL();
private: // Private attributes
/** Eye position distance from coordinate zero point */
GLfloat eyeR;
/** Eye position theta angle from z axis in sterad */
double eyeTheta;
/** Eye position phi angle (longitude) in sterad */
double eyePhi;
/** Light position distance from coordinate zero point */
GLfloat lightR;
/** Light position theta angle from z axis in sterad */
double lightTheta;
/** Light position phi angle (longitude) in sterad */
double lightPhi;
/** 1. pendulum's angle, degree */
GLfloat ang1;
/** 2. pendulum's angle, degree */
GLfloat ang2;
/** 1. pendulum's square root of mass */
GLfloat sqrtm1;
/** 2. pendulum's square root of mass */
GLfloat sqrtm2;
/** 1. pendulum's length */
GLfloat l1;
/** 2. pendulum's length */
GLfloat l2;
/** Pointer to a quadric object used in the rendering function paintGL() */
GLUquadricObj* const quadM1;
/** color of the pendulum bars */
QColor m_barColor;
/** color of the 1. mass */
QColor m_m1Color;
/** color of the 2. mass */
QColor m_m2Color;
};
//--------------------------------------------------------------------
/** @brief Main class of the KPendulum screen saver
*
* This class implements KScreenSaver for the KPendulum screen saver. */
class KPendulumSaver : public KScreenSaver
{
Q_OBJECT
public:
/** @brief Constructor of the KPendulum screen saver object
* @param drawable Id of the window in which the screen saver is drawed
*
* Initial settings are read from disk, the GL widget is set up and displayed
* and the eq. of motion solver is started. */
KPendulumSaver(WId drawable);
/** @brief Destructor of the KPendulum screen saver object
*
* Only KPendulumSaver::solver is destoyed. */
~KPendulumSaver();
/** read the saved settings from disk */
void readSettings();
/** init physical quantities, set up the GL area and (re)start the ode
* solver. Called if new parameters are specified in the setup dialog and at
* startup. */
void initData();
/* accessors for PendulumGLWidget member variables */
/** Set the displayed bar color of the pendulum */
void setBarColor(const QColor& c);
/** Get the displayed bar color of the pendulum */
QColor barColor(void) const;
static const QColor barColorDefault;
/** Set the displayed color of the 1. pendulum mass */
void setM1Color(const QColor& c);
/** Get the displayed color of the 1. pendulum mass */
QColor m1Color(void) const;
static const QColor m1ColorDefault;
/** Set the displayed color of the 2. pendulum mass */
void setM2Color(const QColor& c);
/** Get the displayed color of the 2. pendulum mass */
QColor m2Color(void) const;
static const QColor m2ColorDefault;
/* accessors for own member variables */
/** Set the mass ratio of the pendulum system. @sa
* KPendulumSaver::m_massRatio */
void setMassRatio(const double& massRatio);
/** Get the mass ratio of the pendulum system. @sa
* KPendulumSaver::m_massRatio */
inline double massRatio(void) const {return m_massRatio;}
// lower, upper limits (inclusive) and default values for the setup
// parameters
static const double massRatioLimitUpper;
static const double massRatioLimitLower;
static const double massRatioDefault;
/** Set the length ratio of the pendulum system. @sa
* KPendulumSaver::m_lengthRatio */
void setLengthRatio(const double& lengthRatio);
/** Get the length ratio of the pendulum system. @sa
* KPendulumSaver::m_lengthRatio */
inline double lengthRatio(void) const {return m_lengthRatio;}
static const double lengthRatioLimitLower;
static const double lengthRatioLimitUpper;
static const double lengthRatioDefault;
/** Set the gravitational constant. @sa KPendulumSaver::m_g */
void setG(const double& g);
/** Get the gravitational constant. @sa KPendulumSaver::m_g */
inline double g(void) const {return m_g;}
static const double gLimitLower;
static const double gLimitUpper;
static const double gDefault;
/** Set the total energy. @sa KPendulumSaver::m_E */
void setE(const double& E);
/** Get the total energy. @sa KPendulumSaver::m_E */
inline double E(void) const {return m_E;}
static const double ELimitLower;
static const double ELimitUpper;
static const double EDefault;
/** Set the time interval for the periodic perspective change. @sa
* KPendulumSaver::m_persChangeInterval */
void setPersChangeInterval(const unsigned int& persChangeInterval);
/** Get the time interval for the periodic perspective change. @sa
* KPendulumSaver::m_persChangeInterval */
inline unsigned int persChangeInterval(void) const
{return m_persChangeInterval;}
static const unsigned int persChangeIntervalLimitLower = 5;
static const unsigned int persChangeIntervalLimitUpper = 600;
static const unsigned int persChangeIntervalDefault = 15;
public slots:
/** slot is called if integration should proceed by ::deltaT */
void doTimeStep();
/** slot is called if setup dialog changes in size and the GL are should be
* adjusted */
void resizeGlArea(QResizeEvent* e);
private:
/** The ode solver which is used to integrate the equations of motion */
PendulumOdeSolver* solver;
/** Gl widget of simulation */
PendulumGLWidget* glArea;
/** Timer for the real time integration of the eqs. of motion */
QTimer* timer;
/** Time step size for the integration in milliseconds. 20 ms corresponds to
* a frame rate of 50 fps. */
static const unsigned int deltaT = 20;
static const double eyePhiDefault;
// saved settings
/** Mass ratio m2/(m1+m2) of the pendulum masses. Value is determined by the
* setup dialog. Variable is accessed by setMassRatio() and massRatio(). */
double m_massRatio;
/** Length ratio l2/(l1+l2) of the pendulums. Value is determined by the
* setup dialog. Variable is accessed by setLengthRatio() and
* lengthRatio(). */
double m_lengthRatio;
/** Gravitational constant (in arbitrary units). Value is determined by the
* setup dialog. Variable is accessed by setG() and g(). */
double m_g;
/** Total energy of the system in units of the maximum possible potential
* energy. Value is determined by the setup dialog. Variable is accessed by
* setE() and E(). */
double m_E;
/** Time interval after which a new perspective changed happens. Value is
* determined by the setup dialog. Variable is accessed by
* setPersChangeInterval() and persChangeInterval(). */
unsigned int m_persChangeInterval;
};
//--------------------------------------------------------------------
/** @brief KPendulum screen saver setup dialog.
*
* This class handles the KPendulum screen saver setup dialog. */
class KPendulumSetup : public KPendulumSetupUi
{
Q_OBJECT
public:
/** @brief Constructor for the KPendulum screen saver setup dialog
* @param parent Pointer to the parent widget, passed to KPendulumSetupUi
* @param name Widget name
*
* The dialog box is set up and the screen saver object KPendulumSetup::saver
* is instantiated. */
KPendulumSetup(QWidget* parent = 0, const char* name = 0);
/** @brief Destructor of the KPendulum screen saver setup dialog
*
* Only KPendulumSetup::saver is deleted. */
~KPendulumSetup(void);
public slots:
/** slot for the "OK" button: save settings and exit */
void okButtonClickedSlot(void);
/** slot for the "About" button: show the About dialog */
void aboutButtonClickedSlot(void);
/** slot is called if the mass ratio edit field looses its focus. If the
* input is acceptable KPendulumSaver::setMassRatio() is called. */
void mEditLostFocusSlot(void);
/** slot is called if the length ratio edit field looses its focus. If the
* input is acceptable KPendulumSaver::setLengthRatio() is called. */
void lEditLostFocusSlot(void);
/** slot is called if the gravitational constant edit field looses its focus.
* If the input is acceptable KPendulumSaver::setG() is called. */
void gEditLostFocusSlot(void);
/** slot is called if the energy edit field looses its focus. If the input
* is acceptable KPendulumSaver::setE() is called. */
void eEditLostFocusSlot(void);
/** slot is called if the perspective change interval spin box changed. If
* the input is acceptable KPendulumSaver::setPersChangeInterval() is
* called. */
void persChangeEnteredSlot(int t);
/** slot is called if the bar color button was clicked. A color dialog is
* opened and the result is given to KPendulumSaver::setBarColor(). */
void barColorButtonClickedSlot(void);
/** slot is called if the mass 1 color button was clicked. A color dialog is
* opened and the result is given to KPendulumSaver::setM1Color(). */
void m1ColorButtonClickedSlot(void);
/** slot is called if the mass 2 color button was clicked. A color dialog is
* opened and the result is given to KPendulumSaver::setM2Color(). */
void m2ColorButtonClickedSlot(void);
private:
/** Pointer to the screen saver object. Its member KPendulumSaver::glArea is
* displayed in the preview area */
KPendulumSaver* saver;
};
#endif
|