Lien entre le coefficient directeur d'un tangente et la dérivée

Il s'agit dans cet exemple de tracer la courbe de la fonction inverse, un point M sur l'axe des x puis N le point de même abscisse sur la courbe de la fonction. De plus O l'origine du repère peut être déplacé à l'aide la souris, son déplacement entraine bien sûr le déplacement du repère, de la courbe et des points M et N.

derivee.png

Répertoire : derivee. Trois fichiers sont utilisés : 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/courbe.h"
#include "geo2D/point_sur_droite.h"

class fderivee: public fonction {

public:
    bool def (double);
    double image (double x);
};

class Fenetre: public QWidget {

    Q_OBJECT

public:
    repere *R,*R1;
    droite *ox, *tgte, *MN;
    segment *KL;
    fonction *f;
    fderivee *df;
    courbe *c, *dc;
    point_sur_droite *M;
    pt *N, *L, *K, *O, *O1;
    vecteur *u;

    bool presse;

    Fenetre (QWidget *parent = 0);

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

};

#endif

 

fenetre.cpp

/*
 * fonct
 */

#include "fenetre.h"

#define W 600
#define H 450

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

double fonction::image (double x) {
    return x * cos (x);
}

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

double fderivee::image (double x) {
    return cos (x) - x * sin (x) ;
}

On définit la fonction et sa dérivée

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

    double xM = -1.0;
    R = new repere (300, 200, 600, 800, 50.0, 50.0, 1.0, 1.0);
    O = new pt (0.0, 0.0, "O", R);
    ox = new droite (0.0, 1.0, 0.0, NULL, R);
    M = new point_sur_droite (xM, 0.0, ox, "M", R);
    f = new fonction;
    c = new courbe (f, "y = x cos x", R);

    R1 = new repere (300, 550, 600, 800, 50.0, 50.0, 1.0, 1.0);
    O1 = new pt (0.0, 0.0, "O", R1);
    df = new fderivee;
    dc = new courbe (df, "y = cos x - x sin x", R1);

    double y = (*f).image (xM);
    N = new pt (xM, y, "N", R);
    MN = new droite (1.0, 0.0, - xM, NULL, R);
    u = new vecteur (1.0, (*df).image (xM), NULL, R);
    tgte = new droite (N, u, NULL, R);
    K = new pt (xM, 0.0, "K", R1);
    L = new pt (xM, (*df).image (xM), "N", R1);
    KL = new segment (K, L, NULL, R1);
}

On construit la fenêtre et les objets géométriques.

void Fenetre::paintEvent (QPaintEvent *) {
    setPalette (QPalette (QColor (255, 255, 255)));
    setAutoFillBackground (true);

    QPainter painter (this);
    painter.setPen (Qt::red);
    (*R).trace (&painter);
    (*O).trace (&painter);
    (*R1).trace (&painter);
    (*O1).trace (&painter);
    (*M).trace (&painter);

    painter.setPen (Qt::yellow);
    (*MN).trace (&painter);

    painter.setPen (Qt::black);
    (*KL).trace (&painter);
    (*tgte).trace (&painter);

    painter.setPen (Qt::blue);
    (*c).trace (&painter);
    (*N).trace (&painter);

    painter.setPen (Qt::green);
    (*dc).trace (&painter);
    (*K).trace (&painter);
    (*L).trace (&painter);
}

On trace l'ensemble des objets géométriques.

void Fenetre::mousePressEvent (QMouseEvent *event) {
    int X = (*event).x ();
    int Y = (*event).y ();
    presse = (*M).select (X, Y);
    if (presse)
        setCursor (Qt::ClosedHandCursor);
}

A chaque pression sur la souris, on teste la proximité des coordonnées au seul point déplaçable M.

void Fenetre::mouseMoveEvent (QMouseEvent *event) {
    int X = (*event).x ();
    int Y = (*event).y ();
    if (presse) {
        (*M).bouge (X, Y);
        double xM = (*M).x;
        double y = (*f).image (xM);
        (*N).pt_x_y (xM, y);
        (*MN).droite_a_b_c (1.0, 0.0, - xM);
        (*u).vecteur_x_y (1.0, (*df).image (xM));
        (*tgte).droite_pt_v (N, u);
        (*K).pt_x_y (xM, 0.0);
        (*L).pt_x_y (xM, (*df).image (xM));
        (*KL).segment_pt_pt (K, L);
        update ();

Si le point M est en cours de déplacement, on recalcule tous les éléments géométriques et on redessine le graphique.

    } else {
        if ((*M).zone (X, Y))
            setCursor (Qt::PointingHandCursor);
        else
            setCursor (Qt::ArrowCursor);
    }
}

void Fenetre::mouseReleaseEvent (QMouseEvent *) {
    (*M).stop ();
    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.