Partie 6 :Tracés de courbes

remarques liminaires.

1. Ligne polygonale continue.

Une courbe dessinée sur écran graphique ne doit pas présenter de trous ! Dans la partie 2, on a vu ce que l'on pouvait appeler une ligne "continue", comme ligne limite d'un surface : si on se représente l'écran comme une grille à mailles carrées (un carré=un pixel), deux carrés sont contigus sur une ligne lorsqu'ils ont au moins un sommet en commun. La primitive qui sert présenter le tracé d'un segment de droite joignant deux points respecte cette condition de continuité.

Le plus simple pour tracer une ligne continue est alors de l'identifier à un ligne polygonale dont les sommets sont assez rapprochés : le tracé d'un segment "continu" joignant deux point est alors la primitive utile. La question à se poser est de savoir la longueur maximale des segments pour avoir un bon "lissage" ; ce n'est pas un gros problème, l'œil étant très (très) accommodant de ce point de vue ! Il est possible de créer des primitives plus sophistiquées, comme par exemple une approximation pas splines de la courbe à tracer ; ce n'était pas l'objectif de la question que d'exploiter des outils aussi raffinés !

2. Un tracé sans saccades.

La seconde difficulté est de donner une image en "temps réel", qui saute ni ne clignote pas trop ! Le principe est simple : à environ 20 images par secondes, on est assuré de l'illusion d'un mouvement continu (la télé passe 25 images par secondes, le cinéma amateur 16 images). Si on prend le vingtième de seconde comme base de temps (mais le dixième et même le cinquième seraient acceptables), en une période, on a largement le temps de mener un calcul trigonométrique assez complexe, et l'écran est rafraîchi au moins trois fois. Ni le calcul, ni l'affichage ne sont donc des facteurs limitants, même avec le bon vieux Basic interprété.

3. Question de mathématiques.

Les concepts mathématiques utiles sont ceux vus en classe de troisième : théorème de Thalès, de Pythagore, vecteurs proportionnels, définition des fonctions trigonométriques.

la courbe du chien.

*note sur le tracé du cercle.

Le point M a pour coordonnées :

   X = R cos (a)

   Y = R sin (b)

Une très bonne résolution peut être obtienue en créant un polygone avec autant de côtés qu'il y a de pixels sur un rayon !

* le tracé de la courbe du chien.

Là aussi, on construit la courbe par une suite de segments successifs : A, M1, M2...

Si on appelle (dx, dy) le couple des composantes d'un des vecteurs (MiMi+1), on doit avoir :

dx2 + dy2 = T2 .v2 où T est la base de temps choisie pour le dessin entre deux points.

Et le vecteur doit être colinéaire au vecteur (CM), soit selon le théorème de Thalès :

(X - xi) / dx = (Y- yi) / dy.

Il n'y a de difficulté à calculer dx et dy.

 

procedure TForm1.LeChien;

{-----------------------}

var dX, dY, distance : real;

begin

 with CurChien, ImagePiste.Canvas do

 begin

  dy := -Rayon * sin (omegaPere * (temps-1)) - OldY + CentreY;

  dx := Rayon * cos (omegaPere * (temps-1)) - OldX + CentreX;

  distance := sqrt (dx*dx + dy*dy); {racine carrée}

  dy := (dy / distance) * vitesseChien;

  dx := (dx / distance) * vitesseChien;

  NewX := NewX+dx;

  NewY := NewY+dy;

  moveto (round(OldX), round(OldY));

  lineto (round(NewX), round(NewY));

 end {with}

end;

 

Les courbes des caméras.

 

Il n'y a ici aucune difficulté mathématique : Le point C1 de la figure est le milieu du segment Père-Fils (coordonnées : demi-somme des coordonnées des deux points) ; quant à C2, son abscisse est celle de la position du père et son ordonnées celle du fils. Les techniciens de l'électricité reconnaîtront deux courbes de Lissajous.

Pour C1, d'autres solutions sont possibles puisque la seule condition explicitée dans l'énoncé est que C1 soit sur la médiatrice de Père-Fils ! On peut arbitrairement se donner une seconde contrainte (à condition toutefois que la trajectoire se maintienne dans le carré englobant) : la caméra peut rester liéée à un axe ; ou bien décrire un cercle centré comme la piste.... Attention à la figuration des curseurs !


procedure TForm1.LaDistance;

{--------------------------}

begin

with CurCamera, ImagePiste.Canvas do

 begin

  NewX := CentreX + (round (Rayon * cos(omegaPere*temps)+

            Rayon * cos(omegaFils*temps))) div 2;

  NewY := CentreY - (round (Rayon * sin(omegaPere*temps)+

            Rayon * sin(omegaFils*temps))) div 2;

  moveto (round(OldX), round(OldY));

  lineto (round(NewX), round(NewY));

 end {with}

end;


procedure TForm1.LAngle;

{----------------------}

begin

with CurCamera, ImagePiste.Canvas do

 begin

    NewX := CentreX + round (Rayon * cos(omegaPere*temps));

   NewY := CentreY - round (Rayon * sin(omegaFils*temps));

   moveto (round(OldX), round(OldY));

   lineto (round(NewX), round(NewY));

 end {with}

end;

 

Note sur le source.

Le source de notre réalisation est téléchargeable. Ici également, l'essentiel du code est consacré à l'interface ; un attention particulière a dû être portée aux "curseurs" et à leur croisement. Mais, dans la question telle qu'elle est posée, le problème des curseurs n'est pas primordial (un simple point de couleur est acceptable). La solution est donnée en Pascal (Delphi; fichier d'extension .pas) dont l'écriture des algorithmes est aisément transférable dans tout langage structuré.

téléchargement :