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.
Répertoire : derivee. Trois fichiers sont utilisés : main.cpp, fenetre.h et fenetre.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.
#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
/* * 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.