diff options
Diffstat (limited to 'kscreensaver/kdesavers/pendulum.h')
-rw-r--r-- | kscreensaver/kdesavers/pendulum.h | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/kscreensaver/kdesavers/pendulum.h b/kscreensaver/kdesavers/pendulum.h new file mode 100644 index 00000000..2b917a2b --- /dev/null +++ b/kscreensaver/kdesavers/pendulum.h @@ -0,0 +1,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 |