Courbe d'une fonction dépendant d'un paramètre

Il s'agit dans cet exemple de tracer la courbe de la fonction f (x) = m x2. C'est un curseur qui permet la récupération de la valeur du paramètre m.

fparm.png

Répertoire : fparm. Trois fichiers : main.cpp, fenetre.h et fenetre.cpp.

main.cpp

#include <QApplication>

#include "fenetre.h"

int main (int argc, char *argv []) {
     QApplication app (argc, argv);
     Fenetre f;
     f.show();
     return app.exec ();
}

On crée l'application app, le fenêtre principale f puis on lance la boucle d'exécution app.

fenetre.h

#ifndef FENETRE_H
#define FENETRE_H

#include <QWidget>
#include <QPaintEvent>
#include "geo2D/curseur.h"
#include "geo2D/courbe.h"


class mx2: public fonction {

public:
    double m;
    mx2 (double m);
    double image (double x);
};

La fonction dépendant d'un paramètre est une sur-classe de la classe fonction.

class Fenetre: public QWidget {

    Q_OBJECT

public:
    repere *R;
    curseur *mcurs;
    mx2 *f;
    courbe *c;

On déclare ici tous les objets géométriques qui seront utilisés.

    bool presse;

Indicateur signalant s'il y a un déplacement en cours

    Fenetre (QWidget *parent = 0);

protected:
    void paintEvent (QPaintEvent *);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

};

#endif

On définit ici les quatre fonctions gérant le dessin et l'action de la souris (appui sur le bouton, déplacement, relâchement).

fenetre.cpp

*
 * test
 */

#include "fenetre.h"

bool fonction::def (double) {
    return true;
}

double fonction::image (double) {
    return 0.0;
}

La classe fonction étant virtuelle il faut la définir même si cette définition est bidon.

mx2::mx2 (double m) {
    mx2::m = m;
}

double mx2::image (double x) {
    return m * x * x;
}

On construit ici l'ensemble de définition de la fonction carré mx2 et l'expression de l'image de x.

Fenetre::Fenetre (QWidget *parent): QWidget (parent) {
    setGeometry (0, 0, 600, 450);
    setMouseTracking (true);
    setCursor (Qt::ArrowCursor);
    presse = false;

Constructeur de la fenêtre principale : on indique sa taille, on donne la possibilité de gérer le déplacement de la souris sans qu'on ait besoin d'appuyer sur le bouton (setMouseTracking (true);), on fixe le curseur par défaut puis on initialise l'indicateur de déplacement.

    R = new repere (300, 225, 600, 450, 50.0, 50.0, 1.0, 1.0);
    mcurs = new curseur (-4.0, 4.0, 1.0, 400, 100, 100, "m", R);
    f = new mx2 (1);
    c = new courbe (f, NULL, R);

On crée ici les objets géométriques : le repère, le curseur (de -4 à 4, valeur initiale 1, pas = 100 / 8 = 0,08), la fonction et la courbe de la fonction.

void Fenetre::paintEvent (QPaintEvent *) {
    setPalette (QPalette (QColor (255, 255, 255)));
    setAutoFillBackground (true);
    QPainter painter (this);
    painter.setPen (Qt::red);
    R -> trace (&painter);
    painter.setPen (Qt::blue);
    mcurs -> trace (&painter);
    c -> trace (&painter);
}

On redessine ici la figure : on peint le fond en blanc, on trace le repère en rouge puis le curseur et la courbe.

void Fenetre::mousePressEvent (QMouseEvent *event) {
    int X = event -> x ();
    int Y = event -> y ();
    presse = mcurs -> select (X, Y) || mcurs -> select_curseur (X, Y);
    if (presse)
        setCursor (Qt::ClosedHandCursor);
}

On teste, dans cet ordre, si la souris est proche du bouton du curseur puis du curseur lui-même.

void Fenetre::mouseMoveEvent (QMouseEvent *event) {
    int X = event -> x ();
    int Y = event -> y ();
    if (presse) {
        mcurs -> bouge (X, Y);
        mcurs -> bouge_curseur (X, Y);
        f -> m = mcurs -> valeur ();
        update ();

On met à jour le paramètre puis on relance le tracé..

    } else {
        if (mcurs -> zone (X, Y) || mcurs -> zone_curseur (X, Y))
            setCursor (Qt::PointingHandCursor);
        else
            setCursor (Qt::ArrowCursor);
    }
}

Si on bouge la souris sans appuyer sur le bouton en change simplement le curseur à proximité du curseur ou de son bouton.

void Fenetre::mouseReleaseEvent (QMouseEvent *) {
    mcurs -> stop ();
mcurs -> stop_curseur (); presse = false; setCursor (Qt::PointingHandCursor); }

On relâche de bouton de la souris : on remet alors tous les indicateurs de déplacement à FALSE puis on change le curseur.