C'est une courbe d'équation x2/3 + y2/3 = k que décrit un point d'un cercle qui roule sans glisser à l'intérieur d'un cercle de rayon 4 fois plus grand. L'animation est lancée dès le démarrage : une nouvelle image est calculée toutes les 50ms.

Répertoire : astroide2. Trois fichiers : main.cpp, astroide.h et astroide.cpp.
#include <QApplication>
#include "astroide.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 ASTROIDE_H
#define ASTROIDE_H
#include <QtGui>
#include "geo2D/cercle.h"
#include "geo2D/courbe.h"
class fonction1: public fonction {
public:
bool def (double);
double image (double x);
};
Il faut deux fonctions car x2/3 + y2/3 = k équivaut à y = (k - x2/3)3/2 ou y = - (k - x2/3)3/2.
class Astroide: public QWidget {
Q_OBJECT
public:
repere *R;
pt *O, *M, *P;
cercle *c, *c1;
double angle;
fonction *f;
fonction1 *f1;
courbe *cf, *cf1;
On déclare ici tous les objets géométriques qui seront utilisés.
bool deplace;
Astroide (QWidget *parent = 0);
protected:
void paintEvent (QPaintEvent *);
};
class Fenetre: public QWidget {
Q_OBJECT
public:
QPushButton *bouton;
Astroide *ast;
Fenetre (QWidget *parent = 0);
public slots:
void action ();
};
La fenêtre principale contient le bouton et la feuille de dessin ast.
/*
* astroide2
*
*/
#include "astroide.h"
bool fonction::def (double x) {
return (x >= -4) && (x <= 4);
}
double fonction::image (double x) {
if (x < 0.0)
x = - x;
return pow (2.5198420998 - pow (x, 0.6666666666666), 1.5);
}
bool fonction1::def (double x) {
return fonction::def (x);
}
double fonction1::image (double x) {
return - fonction::image (x);
}
Définition de 2 fonctions : la première est f (x) = (k - x2/3)3/2et la seconde f1 (x) = - f(x).
Astroide::Astroide (QWidget *parent): QWidget (parent) {
QTimer *timer = new QTimer (this);
connect (timer, SIGNAL (timeout ()), this, SLOT (update ()));
timer -> start (50);
On constuit un "timer" qui envoie un signal tous les 50 ms. A chaque "timeout" on redessine la figure. L'instruction connect relie chaque "timout" à la méthode update.
R = new repere (250, 250, 500, 500, 50.0, 50.0, 1.0, 1.0);
O = new pt (0.0, 0.0, NULL, R);
c = new cercle (O, 4, NULL, R);
M = new pt (3.0, 0.0, "M", R);
c1 = new cercle (M, 1, NULL, R);
P = new pt (4, 0, "P", R);
angle = 0.0;
f = new fonction;
cf = new courbe (f, NULL, R);
f1 = new fonction1;
cf1 = new courbe (f1, NULL, R);
On crée ici les objets géométriques.
setWindowTitle (QString::fromUtf8 ("L'Astroïde"));
resize (500, 500);
}
On donne un titre à la fenêtre, sans oublier le fromUtf8 à cause du ï puis on dimensionne la fenêtre.
void Astroide::paintEvent (QPaintEvent *) {
if (angle == 0.0) {
setPalette (QPalette (QColor (255, 255, 255)));
setAutoFillBackground (true);
}
if (deplace) {
angle += 0.02;
M -> pt_x_y (3.0 * cos (angle), 3.0 * sin (angle));
c1 -> cercle_pt_r (M, 1);
P -> pt_x_y (M -> x + cos (angle * 3), M -> y + sin (- angle * 3));
}
QPainter painter (this);
painter.setPen (Qt::red);
R -> trace (&painter);
painter.setPen (Qt::green);
cf -> trace (&painter);
cf1 -> trace (&painter);
painter.setPen (Qt::blue);
c -> trace (&painter);
c1 -> trace (&painter);
P -> trace (&painter);
}
La première fois on peint le fond en blanc.
On ajoute 0.02 à l'angle que fait le petit cercle avec l'axe des abscisses puis on recalcule les coordonnées des points qui se sont déplacés.
Et enfin on redessine le tout.
void Fenetre::action () {
if (ast -> deplace) {
ast -> deplace = false;
bouton -> setText ("Ok");
} else {
ast -> deplace = true;
bouton -> setText ("Stop");
}
}
Un "clic" sur le bouton : onchange l'indicateur deplace puis le texte du bouton.
Fenetre::Fenetre (QWidget *parent): QWidget (parent) {
bouton = new QPushButton ("Ok", this);
bouton-> minimumSize ();
connect (bouton, SIGNAL (clicked ()), this, SLOT (action ()));
ast = new Astroide (parent);
QVBoxLayout *vboite = new QVBoxLayout;
vboite -> addWidget (bouton);
vboite -> addWidget (ast);
setLayout (vboite);
setGeometry (0, 0, 550, 550);
}
Constructeur de la fenêtre principale : on crée le bouton associé à la méthode action() puis la feuille de dessin. On dispose enfin ces deux objets verticalement dans la fenêtre.