//============================================================================ // // KPendulum screen saver for TDE // $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 // TQt headers #include #include #include // GL headers #include #include // TDE headers #include #include "vec3.h" #include "rkodesolver.h" // KPendulumSetupUi #include "pendulumcfg.h" //-------------------------------------------------------------------- /** @brief ODE solver for the Pendulum equations */ class PendulumOdeSolver : public RkOdeSolver { 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 &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 f(const double &x, const std::valarray &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 TQGLWidget to display the KPendulum screen saver. */ class PendulumGLWidget : public TQGLWidget { TQ_OBJECT public: /** @brief Constructor of KPendulum's GL widget * @param parent parent widget, passed to TQGLWidget's constructor * @param name name of widget, passed to TQGLWidget's constructor */ PendulumGLWidget(TQWidget* 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 TQColor& c); /** @brief get color of the bars * @return color */ inline TQColor barColor(void) const {return m_barColor;} /** @brief set color of mass 1 * @param c color */ void setM1Color(const TQColor& c); /** @brief get color of mass 1 * @return color */ inline TQColor m1Color(void) const {return m_m1Color;} /** @brief set color of mass 2 * @param c color */ void setM2Color(const TQColor& c); /** @brief get color of mass 2 * @return color */ inline TQColor 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 */ TQColor m_barColor; /** color of the 1. mass */ TQColor m_m1Color; /** color of the 2. mass */ TQColor m_m2Color; }; //-------------------------------------------------------------------- /** @brief Main class of the KPendulum screen saver * * This class implements KScreenSaver for the KPendulum screen saver. */ class KPendulumSaver : public KScreenSaver { TQ_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 TQColor& c); /** Get the displayed bar color of the pendulum */ TQColor barColor(void) const; static const TQColor barColorDefault; /** Set the displayed color of the 1. pendulum mass */ void setM1Color(const TQColor& c); /** Get the displayed color of the 1. pendulum mass */ TQColor m1Color(void) const; static const TQColor m1ColorDefault; /** Set the displayed color of the 2. pendulum mass */ void setM2Color(const TQColor& c); /** Get the displayed color of the 2. pendulum mass */ TQColor m2Color(void) const; static const TQColor 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(TQResizeEvent* 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 */ TQTimer* 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 { TQ_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(TQWidget* 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