Une droite sur une grille de pixels
Une image numérique est une grille de pixels, repérés par deux coordonnées : x pour la colonne, y pour la ligne. Tracer une droite revient à choisir quels pixels allumer entre deux points.
C’est le premier geste de l’infographie : les lignes d’un schéma, d’un jeu ou d’une carte sont toutes faites ainsi. Vous allez écrire ce calcul vous-même.
À la fin de cette leçon
Remarque
Je peux placer des pixels sur une grille et calculer ceux d’une droite entre deux points.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Pixel | un point de la grille, qu’on allume ou non |
| Coordonnées | deux nombres, x et y, qui repèrent un pixel |
| Pente | de combien la droite monte quand x avance de 1 |
| Rastérisation | le passage d’une forme au choix de pixels |
| Arrondi | le passage à l’entier le plus proche |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Un pixel se repère par x et y
Le pixel en haut à gauche a pour coordonnées (0, 0). Quand x augmente, on va vers la droite. Quand y augmente, on descend : l’axe des y est tourné vers le bas, contrairement à un graphique de mathématiques.
Une grille de 8 colonnes et 4 lignes compte donc 32 pixels, avec x de 0 à 7 et y de 0 à 3.
On avance colonne par colonne
Pour une droite qui monte doucement, on prend chaque colonne x entre les deux extrémités. Pour chacune, on calcule la hauteur y exacte de la droite, puis on l’arrondit pour choisir le pixel.
La formule est : y = y0 + pente × (x − x0). La pente vaut (y1 − y0) divisé par (x1 − x0).
Exemple travaillé : de (0, 0) à (7, 3)
| Colonne x | Hauteur exacte y | Arrondi | Pixel allumé |
|---|---|---|---|
| 0 | 0,00 | 0 | (0, 0) |
| 1 | 0,43 | 0 | (1, 0) |
| 2 | 0,86 | 1 | (2, 1) |
| 3 | 1,29 | 1 | (3, 1) |
| 4 | 1,71 | 2 | (4, 2) |
| 5 | 2,14 | 2 | (5, 2) |
| 6 | 2,57 | 3 | (6, 3) |
| 7 | 3,00 | 3 | (7, 3) |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Calculer les huit pixels de la droite
docker exec jupyter python3 -c "x0,y0,x1,y1=0,0,7,3; print([(x, int(y0+(y1-y0)*(x-x0)/(x1-x0)+0.5)) for x in range(x0,x1+1)])"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ici, pas de carte graphique
Important
Le labo n’a pas de carte graphique. Chaque pixel est calculé par le processeur, en Python, et vous voyez le résultat dans des fichiers PNG ouverts dans JupyterLab. C’est lent, mais on comprend chaque étape.
Voir la hauteur exacte et l’arrondi
# Les pixels d'une droite, de gauche à droite.
x0 = 0
y0 = 0
x1 = 7
y1 = 3
for x in range(x0, x1 + 1):
y = y0 + (y1 - y0) * (x - x0) / (x1 - x0)
print(x, round(y, 2), int(y + 0.5))
# Changez y1 en 5, puis relancez : combien de colonnes gardent la même ligne ?
Une erreur fréquente
Attention
Beaucoup pensent qu’il suffit de couper la partie décimale avec int(y). Ce n’est pas juste : 1,71 deviendrait 1 et non 2, et la droite serait trop basse. Ajoutez 0,5 avant de couper, pour arrondir au plus proche.
Un tableau de pixels devient une image
Pour voir la droite, on crée une image noire de 8 sur 4 pixels. On met chaque pixel de la droite à 255, le blanc. Puis on agrandit l’image dix fois sans lisser, pour que chaque pixel reste un carré net.
Le fichier droite.png s’ouvre ensuite dans JupyterLab.
Dessiner la droite et l’afficher en texte
docker exec jupyter python3 -c "from PIL import Image; im=Image.new('L',(8,4),0); pts=[(x, int(3*x/7+0.5)) for x in range(8)]; [im.putpixel(p,255) for p in pts]; im.resize((80,40),Image.NEAREST).save('droite.png'); print(im.size, sum(1 for v in im.getdata() if v==255)); print('\n'.join(''.join('#' if im.getpixel((x,y)) else '.' for x in range(8)) for y in range(4)))"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ce que la commande a affiché
(8, 4) 8
##......
..##....
....##..
......##
Lire l’image, ligne par ligne
La première ligne du résultat donne la taille, 8 sur 4, et le nombre de pixels blancs, 8 : un par colonne. Les quatre lignes de croix montrent l’escalier.
Dans droite.png, vous voyez huit petits carrés blancs sur un fond noir. Ils descendent par paliers de deux, du coin en haut à gauche vers le coin en bas à droite. Le haut est la ligne 0.