summaryrefslogtreecommitdiffstats
path: root/kscreensaver/kdesavers/rotation.h
diff options
context:
space:
mode:
Diffstat (limited to 'kscreensaver/kdesavers/rotation.h')
-rw-r--r--kscreensaver/kdesavers/rotation.h325
1 files changed, 325 insertions, 0 deletions
diff --git a/kscreensaver/kdesavers/rotation.h b/kscreensaver/kdesavers/rotation.h
new file mode 100644
index 00000000..a1a73867
--- /dev/null
+++ b/kscreensaver/kdesavers/rotation.h
@@ -0,0 +1,325 @@
+//============================================================================
+//
+// KRotation screen saver for KDE
+// Copyright (C) 2004 Georg Drenkhahn
+// $Id$
+//
+//============================================================================
+
+#ifndef __ROTATION_H__
+#define __ROTATION_H__
+
+#include <math.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"
+
+// KRotationSetupUi
+#include "rotationcfg.h"
+
+//--------------------------------------------------------------------
+
+/** @brief ODE solver for the Euler equations.
+ *
+ * Class implements RkOdeSolver<double> to solve the Euler equations of motion
+ * tor the rotating object. */
+class EulerOdeSolver : public RkOdeSolver<double>
+{
+ public:
+ /** @brief Constructor for the ODE solver for the Euler equations.
+ * @param t Time in seconds, integration variable
+ * @param dt Initial time increment in seconds for integration, auto adjusted
+ * later to guarantee precision
+ * @param _A Moment of inertia along 1. figure axis
+ * @param _B Moment of inertia along 2. figure axis
+ * @param _C Moment of inertia along 3. figure axis
+ * @param _y Vector of 12 elements containing the initial rotation vector
+ * omega (elements 0 to 2), and the initial rotating systems coordinate
+ * vectors e1, e2, e3 (elements 3 to 5, 6 to 8, and 9 to 11).
+ * @param eps Relative precision per integration step, see
+ * RkOdeSolver::RkOdeSolver(). */
+ EulerOdeSolver(
+ const double &t_,
+ const double &dt_,
+ const double &A_,
+ const double &B_,
+ const double &C_,
+ std::valarray<double> &y_,
+ const double &eps);
+
+ protected:
+ /** @brief ODE function for the Euler equation system
+ * @param x time in seconds
+ * @param y Vector of 12 elements containing the rotation vector omega
+ * (elements 0 to 2), and the rotating systems coordinate vectors e1, e2, e3
+ * (elements 3 to 5, 6 to 8, and 9 to 11).
+ * @return derivation dy/dx */
+ std::valarray<double>
+ f(const double &x, const std::valarray<double> &y) const;
+
+ private:
+ /** Moments of inertia along the three figure axes */
+ double A, B, C;
+};
+
+
+//--------------------------------------------------------------------
+
+/** @brief GL widget class for the KRotation screen saver
+ *
+ * Class implements QGLWidget to display the KRotation screen saver. */
+class RotationGLWidget : public QGLWidget
+{
+ Q_OBJECT
+
+ public:
+ /** @brief Constructor of KRotation's GL widget
+ * @param parent parent widget, passed to QGLWidget's constructor
+ * @param name name of widget, passed to QGLWidget's constructor
+ * @param omega current rotation vector
+ * @param e1 x trace data
+ * @param e2 y trace data
+ * @param e3 z trace data
+ * @param J 3 vector with momenta of inertia with respect to the 3 figure
+ * axes. */
+ RotationGLWidget(QWidget* parent, const char* name,
+ const vec3<double>& omega,
+ const std::deque<vec3<double> >& e1,
+ const std::deque<vec3<double> >& e2,
+ const std::deque<vec3<double> >& e3,
+ const vec3<double>& J);
+
+ protected:
+ /** Called if scenery (GL view) must be updated */
+ virtual void paintGL();
+ /** Called if gl widget was resized. Method makes adjustments for new
+ * perspective */
+ virtual void resizeGL(int w, int h);
+ /** Setup the GL enviroment */
+ virtual void initializeGL();
+
+ private:
+ /** @brief Draw 3D arrow
+ * @param total_length total length of arrow
+ * @param head_length length of arrow head (cone)
+ * @param base_width width of arrow base
+ * @param head_width width of arrow head (cone)
+ *
+ * The arrow is drawn from the coordinates zero point along th z direction.
+ * The cone's tip is located at (0,0,@a total_length). */
+ void myGlArrow(GLfloat total_length, GLfloat head_length,
+ GLfloat base_width, GLfloat head_width);
+ /** Draw the traces in the GL area */
+ void draw_traces (void);
+
+ private: // Private attributes
+ /** Eye position distance from coordinate zero point */
+ GLfloat eyeR;
+ /** Eye position theta angle from z axis */
+ GLfloat eyeTheta;
+ /** Eye position phi angle (longitude) */
+ GLfloat eyePhi;
+ /** Box size */
+ vec3<double> boxSize;
+ /** GL object list of fixed coordinate systems axses */
+ GLuint fixedAxses;
+ /** GL object list of rotating coordinate systems axses */
+ GLuint bodyAxses;
+ /** Light position distance from coordinate zero point */
+ GLfloat lightR;
+ /** Light position theta angle from z axis */
+ GLfloat lightTheta;
+ /** Light position phi angle (longitude) */
+ GLfloat lightPhi;
+
+ /** stores position where the mouse button was pressed down */
+ QPoint mouse_press_pos;
+
+ /** Length of the rotating coordinate system axses */
+ GLfloat bodyAxsesLength;
+ /** Length of the fixed coordinate system axses */
+ GLfloat fixedAxsesLength;
+
+ /** The openGL rotation matrix for the box. */
+ GLfloat rotmat[16];
+
+ /** reference to current rotation vector */
+ const vec3<double>& omega;
+ /** reference to x trace values */
+ const std::deque<vec3<double> >& e1;
+ /** reference to y trace values */
+ const std::deque<vec3<double> >& e2;
+ /** reference to z trace values */
+ const std::deque<vec3<double> >& e3;
+};
+
+//--------------------------------------------------------------------
+
+/** @brief Main class of the KRotation screen saver
+ *
+ * This class implements KScreenSaver for the KRotation screen saver. */
+class KRotationSaver : public KScreenSaver
+{
+ Q_OBJECT
+
+ public:
+ /** @brief Constructor of the KRotation 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. */
+ KRotationSaver(WId drawable);
+ /** @brief Destructor of the KPendulum screen saver object
+ *
+ * Only KPendulumSaver::solver is destoyed. */
+ ~KRotationSaver();
+ /** read the saved settings from disk */
+ void readSettings();
+ /** init physical quantities and set up the ode solver */
+ void initData();
+
+ /** Returns length of traces in seconds of visibility, parameter from setup
+ * dialog */
+ inline double traceLengthSeconds(void) const {return m_traceLengthSeconds;}
+ /** Sets the length of traces in seconds of visibility. */
+ void setTraceLengthSeconds(const double& t);
+ /** Lower argument limit for setTraceLengthSeconds() */
+ static const double traceLengthSecondsLimitLower;
+ /** Upper argument limit for setTraceLengthSeconds() */
+ static const double traceLengthSecondsLimitUpper;
+ /** Default value of KRotationSaver::m_traceLengthSeconds */
+ static const double traceLengthSecondsDefault;
+
+ /** Flags indicating if the traces for x,y,z are shown. Only relevant if
+ * ::randomTraces is not set to true. Parameter from setup dialog */
+ inline bool traceFlag(unsigned int n) const {return m_traceFlag[n];}
+ /** (Un)Sets the x,y,z traces flags. */
+ inline void setTraceFlag(unsigned int n, const bool& flag)
+ {m_traceFlag[n] = flag;}
+ /** Default values for KRotationSaver::m_traceFlag */
+ static const bool traceFlagDefault[3];
+
+ /** If flag is set to true the traces will be (de)activated randomly all 10
+ * seconds. Parameter from setup dialog */
+ inline bool randomTraces(void) const {return m_randomTraces;}
+ /** (Un)Sets the random trace flag. */
+ inline void setRandomTraces(const bool& flag) {m_randomTraces = flag;}
+ /** Default value for KRotationSaver::m_randomTraces */
+ static const bool randomTracesDefault = true;
+
+ /** Returns the angular momentum. */
+ inline double Lz(void) const {return m_Lz;}
+ /** Sets the angular momentum. */
+ void setLz(const double& Lz);
+ /** Lower argument limit for setLz() */
+ static const double LzLimitLower;
+ /** Upper argument limit for setLz() */
+ static const double LzLimitUpper;
+ /** Default value for KRotationSaver::m_Lz */
+ static const double LzDefault;
+
+ /** Returns initial eulerian angle theta of the top body at t=0 sec. */
+ inline double initEulerTheta(void) const {return m_initEulerTheta;}
+ /** Set the initial eulerian angle theta of the top body at t=0 sec. */
+ void setInitEulerTheta(const double& theta);
+ /** Lower argument limit for setInitEulerTheta() */
+ static const double initEulerThetaLimitLower;
+ /** Upper argument limit for setInitEulerTheta() */
+ static const double initEulerThetaLimitUpper;
+ /** Default value for KRotationSaver::m_initEulerTheta */
+ static const double initEulerThetaDefault;
+
+ 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 area should be
+ * adjusted */
+ void resizeGlArea(QResizeEvent* e);
+
+ private:
+ /** Momentum of inertia along figure axes */
+ vec3<double> J;
+ /** Initial eulerian angles phi of the top body at t=0s */
+ double initEulerPhi;
+ /** Initial eulerian angles psi of the top body at t=0s */
+ double initEulerPsi;
+
+ /** The ode solver which is used to integrate the equations of motion */
+ EulerOdeSolver* solver;
+ /** Gl widget of simulation */
+ RotationGLWidget* glArea;
+ /** Timer for the real time integration of the Euler equations */
+ QTimer* timer;
+
+ /** current rotation vector */
+ vec3<double> omega;
+ /** deque of unit vectors of e1 figure axes in fixed frame coordinates */
+ std::deque<vec3<double> > e1;
+ /** deque of unit vectors of e2 figure axes in fixed frame coordinates */
+ std::deque<vec3<double> > e2;
+ /** deque of unit vectors of e3 figure axes in fixed frame coordinates */
+ std::deque<vec3<double> > e3;
+
+ /** Time step size for the integration in milliseconds. Used in
+ * ::KRotationSaver and ::RotationGLWidget. */
+ static const unsigned int deltaT = 20;
+
+ /** Length of traces in seconds of visibility, parameter from setup dialog */
+ double m_traceLengthSeconds;
+ /** Flags indicating if the traces for x,y,z are shown. Only relevant if
+ * ::randomTraces is not set to true. Parameter from setup dialog */
+ bool m_traceFlag[3];
+ /** If flag is set to true the traces will be (de)activated randomly all 10
+ * seconds. Parameter from setup dialog */
+ bool m_randomTraces;
+ /** Angular momentum. This is a constant of motion and points always into
+ * positive z direction. Parameter from setup dialog */
+ double m_Lz;
+ /** Initial eulerian angles theta of the top body at t=0 sec. Parameter from
+ * setup dialog */
+ double m_initEulerTheta;
+};
+
+//--------------------------------------------------------------------
+
+/** @brief KRotation screen saver setup dialog.
+ *
+ * This class handles the KRotation screen saver setup dialog. */
+class KRotationSetup : public KRotationSetupUi
+{
+ Q_OBJECT
+
+ public:
+ KRotationSetup(QWidget* parent = NULL, const char* name = NULL);
+ ~KRotationSetup();
+
+ 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);
+ void randomTracesToggled(bool state);
+ void xTraceToggled(bool state);
+ void yTraceToggled(bool state);
+ void zTraceToggled(bool state);
+ void lengthEnteredSlot(const QString& s);
+ void LzEnteredSlot(const QString& s);
+ void thetaEnteredSlot(const QString& s);
+
+ private:
+ /// the screen saver widget which is displayed in the preview area
+ KRotationSaver* saver;
+};
+
+#endif