Maths, Informatique, Jeux
Site Web réalisé par Frédéric et François WANG
Répertoire principalInformatiqueProgrammationDiversProgrammation d'instruction graphique

Sommaire

Introduction

Pour vous faciliter l'essais des instructions graphiques, nous utiliserons le QBasic. Il présente l'avantage d'avoir un interpréteur (pas la peine de compiler) et d'être facilement compréhensible même pour les débutants, mais vous pouvez biensûr traduire les procédures dans le langage de votre choix. Le Qbasic possède de nombreuses instructions graphiques pour dessiner points, droites et cercles. Nous ne nous en servirons pas car nous allons redécouvrir comment ce programme ces instructions graphiques... en se servant du mode texte !

Pour reproduire les dessins des courbes, on utilisera la géométrie analytique. La difficulté tiendra dans le fait que les courbes, du plan qui est un ensemble infini se retrouveront représentés dans un ensemble finis de taille 40 × 20. Il y aura donc une perte de la précision et on devra arranger notre programme pour obtenir les meilleurs courbes.

Le fait de savoir calculer les coordonnées des courbes nous sera utile pour d'autres choses que de dessiner à l'écran. En appelant une procédure pour chaque coordonnées de la courbe, le programmeur pourra tracer lignes ou cercles multicolores, faire qu'un objet ait pour trajectoire la courbe...

Le pixel

Le pixel est l'élément de base de nos instructions, il va permettre de faire un « point ». Voici la procédure QBASIC :

SUB AffPixel (x, y)
  IF (x < 0 OR x > 39 OR y < 0 OR y > 19) THEN EXIT SUB
  LOCATE 1 + y, 1 + x * 2: COLOR 15: PRINT CHR$(219) + CHR$(219)
END SUB

On appelle la procédure : CALL AffPixel(19, 10) et on obtient un carré blanc à peu près au centre de l'écran : on a crée notre instruction graphique qui affiche un pixel.

Remarque : on pourrait imaginer d'autres instructions tel que EffPixel(x,y) qui effacerait un pixel, ChgPixel(x,y) qui changerait le pixel en l'affichant ou l'effaçant selon que le pixel est affiché ou non. Une fonction interessante serait ValPixel(x,y) qui retournerait 1 si le pixel est affiché et 0 dans le cas contraitre.

La ligne

L'équation d'une droite est A x + B y + C = 0 . Pour tracer la ligne, on envoie deux coordonnées à la procédure soient ( x 1 , y 1 ) et ( x 2 , y 2 ) .

Puisqu'ils appartiennent à la droite, on a A x 1 + B y 1 + C = 0 et A x 2 + B y 2 + C = 0 . D'où A ( x 1 x 2 ) + B ( y 1 y 2 ) = 0 . On a alors trois cas possible :

Voila pour le coté théorique, maintenant, vérifions par la pratique :

SUB Ligne (x1, y1, x2, y2)

IF x1 = x2 AND y1 = y2 THEN CALL AffPixel(x1, y1): EXIT SUB
IF (x1 = x2) THEN
  FOR y = y1 TO y2 STEP SGN(y2 - y1)
  CALL AffPixel(x1, y)
  NEXT y
ELSE
  a = (y1 - y2) / (x1 - x2): b = y1 - x1 * a
  FOR x = x1 TO x2 STEP SGN(x2 - x1)
  CALL AffPixel(x, a * x + b)
  NEXT x
   END IF

END SUB

Et voici ce que l'on obtient (on ne s'intéresse qu'aux fonctions affines car les autres cas ne posent pas de problèmes) :

Résultat de la procédure Ligne

Lorsque l'on observe les résultats, on voit que même si les fonctions affines sont bijectives, lorsque l'on fait leur représentation à l'écran, ce n'est pas toujours le cas à cause des arrondis.

Cela a pour conséquence que l'on a des « trous » lorsque l'application est injective. Pour résoudre ce problème, on va s'arranger pour n'obtenir que des applications surjectives.

Voici donc finalement la fonction Ligne avec les corrections :

SUB Ligne (x1, y1, x2, y2)

IF x1 = x2 AND y1 = y2 THEN CALL AffPixel(x1, y1): EXIT SUB

  IF ABS(x1 - x2) > ABS(y1 - y2) THEN
    a = (y1 - y2) / (x1 - x2): b = y1 - x1 * a
    FOR x = x1 TO x2 STEP SGN(x2 - x1)
    CALL AffPixel(x, a * x + b)
    NEXT x
  ELSE
    a = (x1 - x2) / (y1 - y2): b = x1 - y1 * a
    FOR y = y1 TO y2 STEP SGN(y2 - y1)
    CALL AffPixel(a * y + b, y)
    NEXT y
  END IF

END SUB

Le cercle

L'équation du cercle de centre ( a ; b ) et de rayon r est ( x a ) 2 + ( y b ) 2 r 2 = 0 . Pour simplifier, on considerera le centre du cercle comme l'origine du repère. L'égalité devient alors x 2 + y 2 r 2 = 0 . On a donc y = ± r 2 x 2 . On va biensûr travailler sur « l'intervalle » [ r , + r ] . Pour éviter les « trous » on peut maintenant relier les points entre eux grâce à l'instruction Ligne. D'où la procédure suivante :

SUB Cercle (a, b, r)
  FOR x = -r + 1 TO r
    CALL Ligne(a + x - 1, b + H(x - 1, r), a + x, b + H(x, r))
    CALL Ligne(a + x - 1, b - H(x - 1, r), a + x, b - H(x, r))
  NEXT x
END SUB

FUNCTION H (x, r)
  H = SQR(r ^ 2 - x ^ 2)
END FUNCTION

Lorsque l'on appelle la procédure (CALL Cercle(15,10,9)) on obtient ceci :
Résultat de la procédure Cercle

Cette page est conforme aux normes du W3C - Auteur : Frédéric WANG - Dernière mise à jour : mardi 17 juin 2003
Valid XHTML 1.1 Valid MathML 2.0 Valid SVG Valid CSS Amaya, the W3C browser/editor Déclaration qualité Opquast Foxkeh banners for Firefox 2