Programmation objet et géométrie/Objets en Python sous Gimp/Tracé de polygones en Python sous Gimp

Un livre de Wikilivres.


Pour Python, un point est un tableau (de deux nombres, l'abscisse et l'ordonnée). Et un polygone est décrit par ses sommets, et sera donc représenté comme un tableau de points ... donc un tableau de tableaux!

C'est pour ce genre de représentations que la programmation objet facilite la compréhension, et raccourcit les scripts.

On va traiter un exemple, celui de la lemniscate de Bernoulli, représentée sous Gimp par une approximation polygonale.

Lemniscate[modifier | modifier le wikicode]

Représentation paramétrique[modifier | modifier le wikicode]

La lemniscate de Bernoulli est donnée par sa représentation paramétrique


Pour la représenter sous Gimp, on va choisir un certain nombre de valeurs de t, pour lesquelles on va calculer x et y. Mais quelques points représentent mal la lemniscate, alors on va les joindre par des segments, qui, s'ils sont assez nombreux, peuvent représenter sous Gimp des coups de pinceau.

Création du filtre[modifier | modifier le wikicode]

Comme d'habitude, on importe les fonctions utiles pour que le script fonctionne (ici on a besoin des fonctions trigonométriques):

#!/usr/bin/env python


import math
from math import *
from gimpfu import *

Script[modifier | modifier le wikicode]

Image et calque[modifier | modifier le wikicode]

La fonction qui implémente le filtre s'appellera python_lemniscate et aura pour variable une image (objet de type image). On récupère trois de ses propriétés:

  1. sa largeur
  2. sa hauteur
  3. son premier calque:
def python_lemniscate(img) :
	largeur=img.width
	hauteur=img.height
	calque=img.layers[0]

Les sommets[modifier | modifier le wikicode]

Les sommets du polygone, construits l'un après l'autres, seront stockés dans un tableau appelé sommets (quel nom original!). Pour utiliser ce tableau, Gimp aura besoin aussi du nombre de sommets, qui s'appellera ns.

Initialisation[modifier | modifier le wikicode]

En phase de test, il est plus prudent de choisir une valeur faible pour ns: Ici on prend 6 sommets, ce qui aura pour effet de faire ressembler la lemniscate à une figure composée de deux carrés ayant un sommet commun. Donc ns est initialisé à 6. Et le tableau sommets est initialement vide:

	ns=6
	sommets=[]

Boucle[modifier | modifier le wikicode]

C'est ici que tout va se passer: Dans la boucle, on va ns fois faire ceci:

  1. Calculer t (le paramètre)
  2. Calculer x avec la représentation paramétrique ci-dessus (mais en modifiant les unités du repère)
  3. Calculer y de même
  4. Créer le point de coordonnées x et y
  5. Stocker ce point dans le tableau sommets.

C'est presque plus court à écrire en Python qu'à décrire:

	for i in range(ns):
		t=2*pi/ns*i
		x=int(largeur/2+largeur/4*cos(t))
		y=int(hauteur/2+hauteur/4*sin(2*t))
		P=(x,y)
		sommets.extend(P)

Fin[modifier | modifier le wikicode]

Pour refermer le polygone, on remet ça une dernière fois: On crée le point initial à nouveau, et on le rajoute dans le tableau. Ainsi le tableau contiendra ns+1 points, donc 2ns+2 nombres entiers:

	x=int(largeur/2+largeur/4)
	y=int(hauteur/2)
	P=(x,y)
	sommets.extend(P)

Tracé au pinceau[modifier | modifier le wikicode]

Pour demander à Gimp de tracer la lemniscate, on va choisir le pinceau par défaut (celui qui est sélectionné au lancement du filtre), lui fournir

  1. le calque sur lequel il va dessiner
  2. la longueur du tableau des sommets
  3. le tableau proprement dit

Le pinceau est appelé dans la base de donnée des procédures (pdb) de Gimp:

	pdb.gimp_paintbrush_default(calque,2*ns+2,sommets)

Récapitulatif[modifier | modifier le wikicode]

L'objet lemniscate est donc celui-ci:

def python_lemniscate(img) :
	largeur=img.width
	hauteur=img.height
	calque=img.layers[0]
	ns=6
	sommets=[]
	for i in range(ns):
		t=2*pi/ns*i
		x=int(largeur/2+largeur/4*cos(t))
		y=int(hauteur/2+hauteur/4*sin(2*t))
		P=(x,y)
		sommets.extend(P)
	x=int(largeur/2+largeur/4)
	y=int(hauteur/2)
	P=(x,y)
	sommets.extend(P)
	pdb.gimp_paintbrush_default(calque,2*ns+2,sommets)

Enregistrement du filtre[modifier | modifier le wikicode]

Pour que le filtre soit accessible depuis le Gimp, on doit ajouter quelque chose comme ceci en bas du script:

register(
       	"lemniscate",
	"Bernoulli",
	"dessin en cours",
	"Auteur du script",
	"Licence GPL",
	"2010",
	"Lemniscate de Bernoulli",
	"*",
	[
	(PF_IMAGE,"img","image vide",None)
	],
	[],
	python_lemniscate,
        menu="<Image>/Filters/Render")

main()

Après ça il suffit d'enregistrer le fichier texte dans le dossier des scripts de Gimp, et de le rendre exécutable, pour avoir le script dans le Gimp, sous la forme d'un filtre de rendu.

Effet obtenu[modifier | modifier le wikicode]

choix du pinceau[modifier | modifier le wikicode]

Ce qui est remarquable à ce stade, c'est que l'effet obtenu va être très différent selon la forme et la taille du pinceau choisis. Par exemple, avec ns=6 et en prenant le pinceau en forme de poivron, on a ceci:

peinture sur toile[modifier | modifier le wikicode]

Et avec une valeur plus raisonnable de 64 pour le nombre ns de sommets, on peut, une fois la lemniscate tracée (ici avec un pinceau "cercle flou de diamètre 8"), appliquer des filtres artistiques de Gimp (ici c'est le filtre toile, mais avec le filtre cubisme on a des résultats assez impressionnants):

Exercice[modifier | modifier le wikicode]

Essayer de reproduire cette image, issue du chapitre sur ImageJ, avec un filtre Python sous Gimp:

Remarque: Ce genre de technique permet aussi de créer des figures géométriques avec le logiciel Inkscape.