Revenir au sommaire Tutoriaux

 


Programmation Delphi

L'API Windows (Application programming interface) fournit deux fonctions, Polybezier et Polybezierto. Elles affichent sur un canvas des courbes de Bézier, à partir d'un tableau de points. Le nombre de points doit être de la forme nx3+1 (points de la courbe + points de contrôle). Le dessin d'effectue avec le stylo courant du canvas : couleur, épaisseur, style et mode. Notez que le mode Notxor est disponible. Il est très pratique pour effacer et redessiner la courbe dans une séquence Onmousemove.

Compatibilité des différentes versions Delphi

En Delphi3 la fonction polybezier n'est pas intégrée à l'objet Tcanvas On utilise donc un appel à polybezier de l'API windows, par exemple :...
BB : array[0..NB] of integer;

...
polybezier(image1.canvas.handle, BB, NB+1);

A partir de Delphi4 ? (j'ai pas testé) ou Delphi5 (testé)  l'objet Tcanvas supporte la fonction Polybezier
Image1.canvas.polybezier(slice(BB, NB+1));

Mais ces fonctions API Windows et Delphi ne nous donnent pas accès au détail du dessin de la courbe. En particulier, elles ne nous permettent pas de savoir si on a cliqué sur un point de la courbe. Les programmes qui suivent utilisent donc à la place la procédure DrawBezier de l'unité Ubezier, qui est de plus compatible avec toutes les versions de Delphi.

Cependant, le tracé par polybezier est plus rapide que la procédure Drawbezier ci-dessous, et il doit être préféré lors des déformations (onmousemove) d'une courbe comportant beaucoup de points (> 10 environ).

Unité UBezier 

Fonctions pour courbes de Bézier

Procedure DrawBezier (ZZ: array of Tpoint;  NB : integer
Cancan : Tcanvas; Bmode : integer;
acolor1, acolor2: tcolor;
var Blength: integer; var Brect: Trect);

Cette procédure dessine sur le canvas Cancan avec la taile et le mode du stylo courant. NB et ZZ correspondent aux paramètres similaires de Polybezier, donc le nombre de points NB doit satisfaire à la formule NB mod 3 = 1.
Drawbezier évalue le pas du paramètre t des équations paramétriques en fonction de la longueur des 3 segments (Pn, Pn+1), (Pn+1, Pn+2), (Pn+2, Pn+3) qui limitent la courbe. Ce pas détermine la précision du tracé. La longueur de ces segments est divisé par 8. Pour une meilleure précision vous pouvez diviser par 4 ou 2.
Pour chaque pas, Drawbezier fait appel à Bcalcul pour obtenir un point de la courbe, et trace un segment de courbe en évitant les points confondus. L'intérêt de Drawbezier est qu'à tout moment nous pouvons intervenir sur le tracé.

Le paramètre Bmode, que vous pouvez enrichir à votre guise, définit l'apparence du tracé. Nous avons prévu :
o Bmode = 0 Rien n'est dessiné, seuls les deux derniers paramètres sont calculés
o Bmode = 1 Dessin de ligne par cancan.moveto une fois et ensuite cancan.lineto avec la couleur acolor1.
o Bmode = 2 Dessin de pixels par cancan.pixels[] := acolor1.  Note : cela permet de voir si le pas du paramètre utilisé donne la précision voulue pour le tracé.
o Bmode = 3 Dessin en dégradé de couleurs entre acolor1 et acolor2
o Bmode = 4 Dessin d'un pseudo sprite rond de couleur acolor2 entouré de acolor1, avec une temporisation (sleep + application.processmessages). Voir cet effet dans le programme Qbezier.exe.

Les deux derniers paramètres sont toujours calculés, et déclarés var, c'est à dire qu'ils sont destinés à récupérer des résutats calculés par Drawbezier :
o Blength donne la longueur en pixels de la courbe de Bézier.
o Brect donne le rectangle délimitant la courbe de Bézier.

 
Function Bcalcul (P1,C1,C2,P2: Tpoint; t: single): Tpoint;

Cette fonction calcule un point de la courbe simple définie par 4 points et le paramètre t, en utilisant les équations de Bézier.

Procedure lissage (var ZZ: Array of Tpoint; NB: integer; acoef: integer);

Les points de la courbe (ouverte ou fermée) ont été placés auparavant aux rangs n mod 3 = 0 dans le tableau ZZ. La fonction applique l'algorithme de lissage décrit plus haut et calcule les points de contrôle avec le coefficient de lissage acoef . Ce paramètre est un pourcentage. Un coefficient de 50 à 70 donne en général un lissage suffisant. Mais pour arrondir un carré en cercle le coefficient vaut environ 105.

Procedure DeCasteljau ( ZZ: array of Tpoint; NB: integer; cancan: Tcanvas;
L1color, L2color, L3color: tcolor; curpt: integer; tt : single);

Cette procédure dessine les segments et les interpolations selon la méthode de de Casteljau. En plus du canvas et du tableau de points, on précise la couleur des segments à dessiner, le rang Curpt du point de départ de la courbe simple (0, 3, 6 ..) et la valeur du paramètre d'interpolation pour cette courbe simple.

Function TangentBezier ( ZZ: array of Tpoint; NB: integer; curpt: integer; tt: single): single;

Cette fonction renvoie l'angle en radians de la tangente au point de la courbe déterminé par le point de départ de la courbe simple et la valeur du paramètre tt qui doit être compris entre 0.0 et 1.0. Utile pour déterminer quelle image d'un sprite on doit afficher, si on lui affecte une trajectoire courbe de Bézier.

Function Nearbezier (ZZ: array of tpoint; NB : integer; ax, ay, tolerance : integer;
var apoint: integer; var aparam : real;): boolean;

Cette fonction permet de détecter si un point est proche d'une courbe de Bézier. Elle renvoie true si la position fournie ax, ay (celle de la souris) se trouve près de la courbe, avec une tolérance en pixels, ce qui permet de corriger l'imprécision due au tracé de la courbe par intervalles (pas) successifs. La fonction renvoie aussi le point commençant la courbe simple et le paramètre du calcul de ce segment de courbe, ce qui permet d'utiliser ultérieurement Bcalcul. Voir l'exploitation de ce résultat dans le programme PBsplit.exe, procédures onnousemove et  onmousedown. La séquence de coupure d'une courbe en deux fait appel à Bcalcul pour reconstituer les points de contrôle, de manière à ce que l'apparence des deux courbes reste la même que la courbe avant la coupure.

Procedure Binterpol ( Z1, Z2 : array of Tpoint; NB : integer; K : single;
var Z3: array of Tpoint);

Cette procédure calcule une courbe de bézier intermédiaire entre 2 coubes de Bézier définies par les points stockés dans Z1 et Z2. Le même nombre de points de contrôle NB est utilisé pour Z1 Z2 et Z3. Le paramètre d'interpolation k est compris entre 0.0 et 1.0 . Voir le programme PBsplit.exe

Fonctions utilitaires de l'unité

Function Egalpoints(pt1, pt2 : tpoint): boolean;

Teste si 2 points sont égaux

Function Interpol(p1, p2 : Tpoint; p : single): Tpoint;

Effectue l'interpolation linéaire entre les 2 points avec p comme coefficient P est l'intervalle 0.0 .. 1.0

Function Arctangente(ax, ay : integer): single;

Calcule l'artangente dans le sens trigonométrique et en radians au point de coordonnées ax et ay par rapport au centre (0,0). Tient compte des valeurs y inversées des coordonnées windows.

Function Distance(x1, y1, x2, y2 : integer): integer;

Calcule en pixels la distance entre 2 points par la formule de Taylor, qui est environ 2 fois plus rapide que la formule de pythagore: Hypothénuse = sqrt(sqr(x1-x2)+sqr(y1-y2))

Programme de démonstration PCastel.exe

Projet PCastel.dpr, unités Ucastel.pas et Tbezier.pas

Ce programme utilise une courbe simple, qui comporte donc 2 extrémités et 2 points de contrôle. Elle montre la construction de de Casteljau.
- Déplacement des points de la courbe et des points de contrôle à la souris. Déformations .
- Tracé de courbe en mode ligne ou pointillés. Les pointillés montrent l'incidence du nombre de pas calculé par drawbezier sur la précision du tracé.
- Cocher la case à cocher "Construction de de Casteljau". Faire varier le curseur à la souris ou avec les touches flèchées pour voir comment la courbe se construit.
Le programme indique la longueur de la courbe et l'angle de la tangente au point courant de la courbe. 

Programme de démonstration PBSplit.exe

Projet Pbsplit.dpr, unités Ubsplit.pas et Tbezier.pas

Coupure d'une courbe en deux. Interpolation. Tracé de courbe de bézier en dégradé.
Ce programme montre au départ une courbe simple. Quand le curseur change de forme, vous pouvez cliquer sur la courbe pour la couper en deux. Quand la courbe est coupée en deux et si la case interpolation est cochée, la courbe intermédiaire entre les deux courbes s'affiche. Vous pouvez en plus cocher la case trace pour visualiser la surface générée en faisant le varier coefficient d'interpolation à l'aide du trackbar. La couleur de la courbe de bézier est dégradée. la surface est mieux visible avec le case "gras" cochée.

Programme de démonstration QBezier.exe

Projet Qbezier.dpr, unités QbezierU.pas et Tbezier.pas

Ce programme utilise une courbe composée de plusieurs points (pas simple). la courbe peut être ouverte ou fermée.

Au départ, le programme affiche 4 points de la courbe (de rang n tel que n mod 3 = 0) formant un carré. Noter qu'il existe en fait 5 points, les points n°0 et n° 4 étant confondus puisque la courbe est fermée. Un coefficient de lissage de 105 % est appliqué et cela donne un cercle correctement arrondi. Les points de contrôle calculés par l'algorithme de lissage sont affichés en rouge (point "à droite" de rang n tel que n mod 3 = 1) et en bleu (point "à gauche " de rang n tel que n mod 3 = 2).

Vous pouvez utiliser cet exemple pour faire varier (bouton updown) le coefficient de lissage et constater le passage progressif du cercle en carré et réciproquement.
Attention : si vous appuyez volontairement ou par erreur sur le bouton Lissage, ou si vous faites varier le coefficient de lissage, vous perdrez le travail sur la  figure courante, puisque tous les points de contrôle seront recalculés.

Nouvelle courbe : Vous pouvez choisir le nombre de segments de la courbe, et si la courbe sera ouverte ou fermée, avant ou parès le clic sur le bouton nouveau. Si la courbe est fermée, un polygone régulier est créé et lissé. Si la courbe est ouverte, une espèce de sinusoïde est créée.

Déformations : Vous pouvez cliquer-tirer sur les points de la courbe et sur les points de contrôle comme vous le souhaitez.
Pour vous aider à réussir plus facilement vos dessins, des options de symétrie sont disponibles :
- Aucune symétrie : seul le point cliqué évolue.
- Totale : la symétrie centrale s'applique à tous les points de même type en même temps: points de la courbe, ou points de contrôle à gauche, ou points de contrôle à droite. Cette option est recommandée avec les polygones : scie circulaire, étoiles, fleurs.
- Centrale : le point symétrique du point cliqué reste symétrique par rapport au centre.
- Verticale : le point symétrique du point cliqué bouge symétriquement par rapport à l'axe des ordonnées (y). C'est à dire que vous obtenez une figure avec une symétrie verticale, comme par exemple la tour Eiffel.

Rectangle : Un clic sur ce bouton dessine le rectangle limitant la courbe de Bézier, information donnée par la procédure Drawbezier.

Sprite : Un clic sur ce bouton fait parcourir la courbe par un sprite. On voit que quand la courbure est grande, le sprite ralentit dans les virages ….

Courbes d'exemple : Elles sont alimentées à l'aide de la combobox : cœur, lemniscate de Bernouilli, œuf, fleur, pièce de puzzle. Ces courbes sont alimentées à partir de fichiers existants .dat.

Enregistrement d'une courbe. le menu Fichier >> Enregistrer vous demande de donner un titre à la courbe. On vous propose de l'enregistrer avec ce nom suffixé par .dat (ou.txt). Ce ficher texte contient le nom de la courbe, le nombre de points -1, et les coordonnées des points relatives au centre de l'image.

Lecture d'une courbe. Le menu Fichier >> Lecture alimente un fichier à extension .txt ou .dat avec quelque contrôles. Vous pouvez par exemple charger le fichier Airfoil.dat qui représente un profil d'aile d'avion (en définissant seulement 13 points de la courbe de Bézier, au lieu d'une soixantaine avec une liste de coordonnéees).

Cliquez ici pour Télécharger les sources (26K)


Revenir au sommaire Tutoriaux