Espoir
This commit is contained in:
parent
41d3bd84a7
commit
cabf456282
117
Chapitre 2 - Récursivité/C06_tp_fractales_arbres.py
Normal file
117
Chapitre 2 - Récursivité/C06_tp_fractales_arbres.py
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
# Chapitre 6 - TP 2 - Dessiner des fractales (page 129)
|
||||||
|
#
|
||||||
|
|
||||||
|
from math import cos, sin, radians
|
||||||
|
from matplotlib.colors import rgb2hex
|
||||||
|
from dessin import Dessin, Trait, Arc, main_loop
|
||||||
|
|
||||||
|
|
||||||
|
# constantes
|
||||||
|
TAILLE = 800 # taille de la surface de dessin
|
||||||
|
# la surface de dessin, avec un fond blanc
|
||||||
|
dessin_arbre = Dessin("white", TAILLE, TAILLE)
|
||||||
|
|
||||||
|
|
||||||
|
def ytree(
|
||||||
|
n,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
orientation_arbre,
|
||||||
|
longueur,
|
||||||
|
ecart_angulaire_fils=radians(22.5),
|
||||||
|
ratio_longueur=0.8,
|
||||||
|
n_max=None,
|
||||||
|
):
|
||||||
|
""" Dessine un arbre binaire ytree de hauteur n+1.
|
||||||
|
Entrée:
|
||||||
|
- n : hauteur de l'arbre courant -1
|
||||||
|
- x,y : coordonnées de la racine de l'arbre
|
||||||
|
- orientation_arbre : orientation de l'arête partant de la racine du y-tree courant, en radians: radians(0) si horizontale, radians(90) = pi/2 pour orienter verticalement vers le haut
|
||||||
|
- longueur : longueur de l'arête partant de la racine du y-tree courant
|
||||||
|
- ratio_longueur : le ratio servant à diminuer la longueur d'un niveau à l'autre.
|
||||||
|
- n_max : le nombre de niveaux de l'arbre global. Utilisé uniquement pour attribuer la bonne couleur en fonction du niveau du y-tree courant dans l'arbre global.
|
||||||
|
-------
|
||||||
|
Un y-tree de niveau 1 (n=1) est un simple trait.
|
||||||
|
Un y-tree de niveau n>=2 est formé d'un trait suivi de 2 y-trees de niveau n-1.
|
||||||
|
Dans un y-tree:
|
||||||
|
=> c'est l'arête rejoignant un noeud à son père qui est l'axe de symétrie entre ses 2 sous-arbres.
|
||||||
|
=> l'angle entre les fils est constant: 2*ecart_angulaire_fils, donc chaque arête s'écarte de l'arête parente d'un angle +/-'ecart_angulaire_fils'.
|
||||||
|
On a choisi de diminuer la longueur d'un facteur constant à chaque niveau.
|
||||||
|
Les branches sont colorées proportionnellement à leur niveau dans l'arbre :
|
||||||
|
=> le lien partant de la racine globale est noir
|
||||||
|
=> pour n >= 2, les liens aboutissant aux feuilles sont verts
|
||||||
|
-------
|
||||||
|
Complexité: linéaire dans la taille de l'arbre.
|
||||||
|
"""
|
||||||
|
if n >= 0:
|
||||||
|
if n_max == None:
|
||||||
|
n_max = n
|
||||||
|
x1 = x + cos(orientation_arbre) * longueur
|
||||||
|
y1 = y + sin(orientation_arbre) * longueur
|
||||||
|
couleur = rgb2hex((0.0, 1.0, 0.0))
|
||||||
|
if n_max >= 1:
|
||||||
|
couleur = rgb2hex((0.0, float(n_max - n) / (n_max), 0.0))
|
||||||
|
Trait(dessin_arbre, x, y, x1, y1, couleur)
|
||||||
|
ytree(n-1, x1, y1, orientation_arbre + ecart_angulaire_fils, longueur*ratio_longueur, ecart_angulaire_fils, ratio_longueur, n_max)
|
||||||
|
ytree(n-1, x1, y1, orientation_arbre - ecart_angulaire_fils, longueur*ratio_longueur, ecart_angulaire_fils, ratio_longueur, n_max)
|
||||||
|
# A compléter
|
||||||
|
# Pour effectuer les appels récursifs :
|
||||||
|
# - ecart_angulaire_fils, ratio_longueur, n_max ne changent pas
|
||||||
|
# - la nouvelle origine est x1, y1
|
||||||
|
# - la longueur diminue et devient longueur*ratio_longueur
|
||||||
|
# - l'orientation des sous-arbre est obtenue en fonction de orientation_arbre et ecart_angulaire_fils
|
||||||
|
|
||||||
|
|
||||||
|
def dessiner_arbre_binaire_arc(n, x, y, w):
|
||||||
|
""" Dessine un arbre binaire de hauteur n+1, en représentant les arêtes par des arcs de cercle.
|
||||||
|
Entrée:
|
||||||
|
- x,y : coordonnées de la racine de l'arbre
|
||||||
|
- w : écart horizontal entre les 2 fils de la racine.
|
||||||
|
- h : écart vertical entre 2 niveaux
|
||||||
|
- n : hauteur de l'arbre courant -1
|
||||||
|
-------
|
||||||
|
L'arbre est représenté verticalement de haut en bas.
|
||||||
|
Les 2 noeuds sont reliés par des arcs de cercles à leurs parents (1/4 de cercle pour chaque fils, de manière à former un demi-cercle d'un fils à l'autre).
|
||||||
|
=> C'est l'axe vertical qui est l'axe de symétrie entre les 2 sous-arbres.
|
||||||
|
=> En divisant w par 2 à chaque niveau, on a la garantie que les branches ne se croisent pas (et comme les noeuds sont de simples points qui n'ont pas de largeur, il n'y a pas de risque que les feuilles se recouvrent).
|
||||||
|
-------
|
||||||
|
Complexité: linéaire dans la taille de l'arbre.
|
||||||
|
"""
|
||||||
|
if n > 0:
|
||||||
|
Arc(dessin_arbre, x - w / 2, y, x + w / 2, y + w, 0, 180)
|
||||||
|
dessiner_arbre_binaire_arc(n-1, x-w/2, y+w/2, w/2)
|
||||||
|
dessiner_arbre_binaire_arc(n-1, x+w/2, y+w/2, w/2)
|
||||||
|
|
||||||
|
|
||||||
|
def dessiner_arbre_binaire_trait(n, x, y, w, h):
|
||||||
|
""" Dessine un arbre binaire classique de hauteur n+1.
|
||||||
|
Entrée:
|
||||||
|
- x,y : coordonnées de la racine de l'arbre
|
||||||
|
- w : écart horizontal entre les 2 fils de la racine.
|
||||||
|
- h : écart vertical entre 2 niveaux
|
||||||
|
- n : hauteur de l'arbre courant -1
|
||||||
|
-------
|
||||||
|
L'arbre est représenté verticalement de haut en bas.
|
||||||
|
=> C'est l'axe vertical qui est la bisectrice entre les 2 arêtes rejoignant un noeud à ses fils.
|
||||||
|
=> En divisant w par 2 à chaque niveau, on a la garantie que les branches ne se croisent pas (et comme les noeuds sont de simples points qui n'ont pas de largeur, il n'y a pas de risque que les feuilles se recouvrent).
|
||||||
|
A vous de modifier pour que cet arbre soit fractal en modifiant l'écart vertical.
|
||||||
|
Tel qu'il est écrit en l'absence de modification, cet arbre n'est pas réellement fractal car l'angle entre les fils varie à chaque niveau (donc en "zoomant" on n'a pas exactement la même figure que la figure globale).
|
||||||
|
-------
|
||||||
|
Complexité: linéaire dans la taille de l'arbre.
|
||||||
|
"""
|
||||||
|
# A modifier :
|
||||||
|
if n > 0:
|
||||||
|
Trait(dessin_arbre, x, y, x - w / 2, y + h)
|
||||||
|
Trait(dessin_arbre, x, y, x + w / 2, y + h)
|
||||||
|
dessiner_arbre_binaire_trait(n - 1, x - w / 2, y + h, w / 2, h)
|
||||||
|
dessiner_arbre_binaire_trait(n - 1, x + w / 2, y + h, w / 2, h)
|
||||||
|
|
||||||
|
|
||||||
|
# Test :
|
||||||
|
ytree(10, 100, 200, 0, 50, radians(22.5), .8)
|
||||||
|
dessiner_arbre_binaire_arc(5, 600, 20, 160)
|
||||||
|
dessiner_arbre_binaire_trait(5, 600, 400, 160, 40)
|
||||||
|
|
||||||
|
main_loop()
|
BIN
Chapitre 2 - Récursivité/__pycache__/dessin.cpython-311.pyc
Normal file
BIN
Chapitre 2 - Récursivité/__pycache__/dessin.cpython-311.pyc
Normal file
Binary file not shown.
511
Chapitre 2 - Récursivité/dessin.py
Normal file
511
Chapitre 2 - Récursivité/dessin.py
Normal file
|
@ -0,0 +1,511 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bibliothèque de dessin pour le TP du C06 et l'activité du C07.
|
||||||
|
#
|
||||||
|
# Cette bibliothèque définit un classe Dessin pour créer une surface de dessin :
|
||||||
|
# s = Dessin()
|
||||||
|
# et les classes Disque, Trait, Rectangle pour créer des formes que l'on peut ensuite modifier
|
||||||
|
# d = Disque(s, 40, 50, 10, 'red') # disque de centre (40, 50), de rayon 10 et de couleur rouge
|
||||||
|
# t = Trait(s, 10, 20, 100, 100, 'blue') # trait de (10, 20) à (100, 100) de couleur bleue
|
||||||
|
# r = Rectangle(s, 100, 20, 200, 120, 'green') # rectangle de coins (100, 20) et (200, 120), de couleur verte
|
||||||
|
# a = Arc(s, 10, 20, 100, 120, 45, 90, 'red') # arc de cercle ou d'ellipse contenu dans le rectangle (10, 20), (100, 120),
|
||||||
|
# commençant à 45º et de longueur 90º, de couleur rouge
|
||||||
|
# t = Texte(s, 100, 200, "Hello", 'black') # texte "Hello" centré à la position 100, 200, de couleur noire
|
||||||
|
#
|
||||||
|
# Note : chaque constructeur peut prendre des paramètres optionnels supplémentaires :
|
||||||
|
# Dessin: couleur de fond, largeur, hauteur
|
||||||
|
# Disque, Rectangle : épaisseur du bord, couleur du bord (pas de bord par défaut)
|
||||||
|
# Trait, Arc : épaisseur du trait (1 par défaut)
|
||||||
|
# Texte : police (triplet nom de police, taille, style), ancre (point cardinal par rapport auquel le texte est positionné)
|
||||||
|
#
|
||||||
|
# Les méthodes disponibles sur une forme f :
|
||||||
|
# f.couleur('yellow') changer la couleur de remplissage (sauf Trait et Arc)
|
||||||
|
# f.epaisseur(4) changer l'épaisseur du bord ou du trait
|
||||||
|
# f.bord('black') changer la couleur du bord (pour le trait et l'arc utiliser f.couleur)
|
||||||
|
# f.rayon(20) changer le rayon (Disque seulement)
|
||||||
|
# f.angle_debut(90) changer l'angle de début (Arc seulement)
|
||||||
|
# f.largeur_angulaire(180) changer la longueur de l'arc (Arc seulement)
|
||||||
|
# f.police(("Times", 12, "bold")) changer la police de caractères (Texte seulement)
|
||||||
|
# f.ancre('nord-est') changer la position relative du texte (Texte seulement, voir code ci-dessous)
|
||||||
|
#
|
||||||
|
# f.bouge(10, 20) déplacer la forme de 10 pixels en x et 20 pixels en y
|
||||||
|
# f.bouge_1(10, 20) déplacer le premier point de la forme (Rectangle, Trait et Arc seulement)
|
||||||
|
# f.bouge_2(10, 20) déplacer le second point de la forme (Rectangle, Trait et Arc seulement)
|
||||||
|
#
|
||||||
|
# f.position(50, 70) déplacer la forme pour que son centre soit à la position (50, 70)
|
||||||
|
# f.position_1(50, 70) déplacer le premier point de la forme à cette position (Rectangle, Trait et Arc seulement)
|
||||||
|
# f.position_2(50, 70) déplacer le second point de la forme à cette position (Rectangle, Trait et Arc seulement)
|
||||||
|
#
|
||||||
|
# f.dessous() mettre la forme f en-dessous de toutes les autres
|
||||||
|
# f.dessus() mettre la forme f au-dessus de toutes les autres
|
||||||
|
# f.efface() effacer la forme, qui devient alors inutilisable (les autres méthodes de font rien)
|
||||||
|
#
|
||||||
|
# Enfin on peut animer le dessin grâce à la méthode `anime` de la classe Surface :
|
||||||
|
# s.anime(50, pas) # appelle la fonction `pas` toutes les 50 millisecondes
|
||||||
|
# s.arrete() # arrête l'animation
|
||||||
|
#
|
||||||
|
# IMPORTANT :
|
||||||
|
# La fonction main_loop() doit être appelée à la fin du programme principal
|
||||||
|
# pour lancer la boucle d'interaction.
|
||||||
|
|
||||||
|
# Eviter le bug qui plante (certains) MacOS avec TkInter et Python3 !
|
||||||
|
import platform
|
||||||
|
|
||||||
|
# if platform.mac_ver()[0] != '' and platform.python_version_tuple()[0] != '2':
|
||||||
|
# exit('TkInter crashes on this Mac with Python 3. Use Python 2.x')
|
||||||
|
|
||||||
|
# Importer la bonne version de TkInter
|
||||||
|
|
||||||
|
import tkinter as tk
|
||||||
|
|
||||||
|
_root = tk.Tk()
|
||||||
|
|
||||||
|
|
||||||
|
def main_loop():
|
||||||
|
""" Lancer la boucle d'interaction """
|
||||||
|
tk.mainloop()
|
||||||
|
|
||||||
|
|
||||||
|
class Dessin:
|
||||||
|
""" Cette classe représente une surface de dessin.
|
||||||
|
Toutes les autres classes prennent une instance de cette classe dans leur constructeur.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, fond="white", largeur=800, hauteur=800):
|
||||||
|
# créer une surface de dessin qui remplit la fenêtre
|
||||||
|
self.canvas = tk.Canvas(_root, bg=fond, width=largeur, height=hauteur)
|
||||||
|
self.canvas.pack(expand=True, fill="both")
|
||||||
|
self.stop_animation = False
|
||||||
|
|
||||||
|
def anime(self, dt, pas):
|
||||||
|
""" Appeler la fonction `pas` toutes les dt ms """
|
||||||
|
pas()
|
||||||
|
if not self.stop_animation:
|
||||||
|
self.canvas.after(dt, lambda: self.anime(dt, pas))
|
||||||
|
self.stop_animation = False
|
||||||
|
|
||||||
|
def arrete(self):
|
||||||
|
""" Arrêter l'animation """
|
||||||
|
self.stop_animation = True
|
||||||
|
|
||||||
|
|
||||||
|
class Disque:
|
||||||
|
""" Cette classe représente un disque de centre, rayon et couleur donnés.
|
||||||
|
Le disque peut avoir un bord d'épaisseur et de couleur donnés.
|
||||||
|
Si la couleur de remplissage est '', le disque est "vide",
|
||||||
|
et si son épaisseur de bord n'est pas nulle, il s'affiche comme un cercle.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, dessin, x, y, r, couleur='black', epaisseur=0, bord="black"):
|
||||||
|
self.dessin = dessin
|
||||||
|
self.item = dessin.canvas.create_oval(
|
||||||
|
x - r, y - r, x + r, y + r, fill=couleur, width=epaisseur, outline=bord
|
||||||
|
)
|
||||||
|
|
||||||
|
def couleur(self, c):
|
||||||
|
""" Changer la couleur du disque """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, fill=c)
|
||||||
|
|
||||||
|
def epaisseur(self, e):
|
||||||
|
""" Changer l'épaisseur du bord du disque """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, width=e)
|
||||||
|
|
||||||
|
def bord(self, c):
|
||||||
|
""" Changer la couleur du bord du disque """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, outline=c)
|
||||||
|
|
||||||
|
def rayon(self, r):
|
||||||
|
""" Changer le rayon du disque """
|
||||||
|
if self.item:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
x, y = (x1 + x2)/2, (y1 + y2)/2
|
||||||
|
self.dessin.canvas.coords(self.item, x - r, y - r, x + r, y + r)
|
||||||
|
|
||||||
|
def position(self, x, y):
|
||||||
|
""" Changer la position du disque """
|
||||||
|
if self.item:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
r = (x2 - x1)/2
|
||||||
|
self.dessin.canvas.coords(self.item, x - r, y - r, x + r, y + r)
|
||||||
|
|
||||||
|
def bouge(self, dx, dy):
|
||||||
|
""" Déplacer le disque de dx, dy """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.move(self.item, dx, dy)
|
||||||
|
|
||||||
|
def dessus(self):
|
||||||
|
""" Placer le disque au-dessus des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_raise(self.item)
|
||||||
|
|
||||||
|
def dessous(self):
|
||||||
|
""" Placer le disque en dessous des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_lower(self.item)
|
||||||
|
|
||||||
|
def efface(self):
|
||||||
|
""" Effacer le disque, qui ne peut plus alors être utilisé """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.delete(self.item)
|
||||||
|
self.item = None
|
||||||
|
|
||||||
|
|
||||||
|
class Trait:
|
||||||
|
""" Cette classe représente un trait d'extrémités et de couleur donnés """
|
||||||
|
|
||||||
|
def __init__(self, dessin, x1, y1, x2, y2, couleur="black", epaisseur=1):
|
||||||
|
self.dessin = dessin
|
||||||
|
self.item = dessin.canvas.create_line(
|
||||||
|
x1, y1, x2, y2, fill=couleur, width=epaisseur
|
||||||
|
)
|
||||||
|
|
||||||
|
def couleur(self, c):
|
||||||
|
""" Changer la couleur du trait """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, fill=c)
|
||||||
|
|
||||||
|
def epaisseur(self, e):
|
||||||
|
""" Changer l'épaisseur du trait """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, width=e)
|
||||||
|
|
||||||
|
def position(self, x, y):
|
||||||
|
""" Changer la position du (milieu du) trait """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
|
||||||
|
self.dessin.canvas.move(self.item, x - cx, y - cy)
|
||||||
|
|
||||||
|
def position_1(self, x, y):
|
||||||
|
""" Changer la position de la première extrémité du trait """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x, y, x2, y2)
|
||||||
|
|
||||||
|
def position_2(self, x, y):
|
||||||
|
""" Changer la position de la seconde extrémité du trait """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1, y1, x, y)
|
||||||
|
|
||||||
|
def bouge(self, dx, dy):
|
||||||
|
""" Déplacer le trait de dx, dy """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.move(self.item, dx, dy)
|
||||||
|
|
||||||
|
def bouge_1(self, dx, dy):
|
||||||
|
""" Déplacer la première extrémité du trait de dx, dy """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1 + dx, y1 + dy, x2, y2)
|
||||||
|
|
||||||
|
def bouge_2(self, dx, dy):
|
||||||
|
""" Déplacer la seconde extrémité du trait de dx, dy """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1, y1, x2 + dx, y2 + dy)
|
||||||
|
|
||||||
|
def dessus(self):
|
||||||
|
""" Placer le trait au-dessus des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_raise(self.item)
|
||||||
|
|
||||||
|
def dessous(self):
|
||||||
|
""" Placer le trait en dessous des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_lower(self.item)
|
||||||
|
|
||||||
|
def efface(self):
|
||||||
|
""" Effacer le trait, qui ne peut plus alors être utilisé """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.delete(self.item)
|
||||||
|
self.item = None
|
||||||
|
|
||||||
|
|
||||||
|
class Arc:
|
||||||
|
""" Cette classe représente un arc de cercle donné par le carré qui l'encadre,
|
||||||
|
l'angle de départ, la largeur angulaire, et sa couleur
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
dessin,
|
||||||
|
x_min,
|
||||||
|
y_min,
|
||||||
|
x_max,
|
||||||
|
y_max,
|
||||||
|
s_angle,
|
||||||
|
largeur_angulaire,
|
||||||
|
couleur="black",
|
||||||
|
epaisseur=1,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
x_min, y_min, x_max, y_max : coordonnées du carré contenant le cercle complet
|
||||||
|
s_angle : angle en degré du départ de l'arc par rapport à l'axe des x : 0 est situé à 3h, 90 à 12h...
|
||||||
|
largeur_angulaire : largeur angulaire de l'arc, en degré (180 pour un demi-cercle)
|
||||||
|
"""
|
||||||
|
self.dessin = dessin
|
||||||
|
# dans canvas un arc est créé par
|
||||||
|
self.item = dessin.canvas.create_arc(
|
||||||
|
x_min,
|
||||||
|
y_min,
|
||||||
|
x_max,
|
||||||
|
y_max,
|
||||||
|
start=s_angle,
|
||||||
|
extent=largeur_angulaire,
|
||||||
|
outline=couleur,
|
||||||
|
width=epaisseur,
|
||||||
|
style="arc",
|
||||||
|
)
|
||||||
|
|
||||||
|
def couleur(self, c):
|
||||||
|
""" Changer la couleur du trait """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, outline=c)
|
||||||
|
|
||||||
|
def epaisseur(self, e):
|
||||||
|
""" Changer l'épaisseur du trait """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, width=e)
|
||||||
|
|
||||||
|
def dessus(self):
|
||||||
|
""" Placer le rectangle au-dessus des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_raise(self.item)
|
||||||
|
|
||||||
|
def angle_debut(self, a):
|
||||||
|
""" Changer l'épaisseur du trait """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, start=a)
|
||||||
|
|
||||||
|
def largeur_angulaire(self, a):
|
||||||
|
""" Changer l'épaisseur du trait """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, extent=a)
|
||||||
|
|
||||||
|
def position(self, x, y):
|
||||||
|
""" Changer la position du centre de l'arc """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
|
||||||
|
self.dessin.canvas.move(self.item, x - cx, y - cy)
|
||||||
|
|
||||||
|
def position_1(self, x, y):
|
||||||
|
""" Changer la position du premier coin du rectangle englobant de l'arc """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x, y, x2, y2)
|
||||||
|
|
||||||
|
def position_2(self, x, y):
|
||||||
|
""" Changer la position du second coin du rectangle englobant de l'arc """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1, y1, x, y)
|
||||||
|
|
||||||
|
def bouge(self, dx, dy):
|
||||||
|
""" Déplacer l'arc de dx, dy """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.move(self.item, dx, dy)
|
||||||
|
|
||||||
|
def bouge_1(self, dx, dy):
|
||||||
|
""" Déplacer le premier coin du rectangle englobant de l'arc """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1 + dx, y1 + dy, x2, y2)
|
||||||
|
|
||||||
|
def bouge_2(self, dx, dy):
|
||||||
|
""" Déplacer le second coin du rectangle englobant de l'arc """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1, y1, x2 + dx, y2 + dy)
|
||||||
|
|
||||||
|
def dessous(self):
|
||||||
|
""" Placer le rectangle en dessous des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_lower(self.item)
|
||||||
|
|
||||||
|
def efface(self):
|
||||||
|
""" Effacer le trait, qui ne peut plus alors être utilisé """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.delete(self.item)
|
||||||
|
self.item = None
|
||||||
|
|
||||||
|
|
||||||
|
class Rectangle:
|
||||||
|
""" Cette classe représente un rectangle de coordonnées et de couleur donnés.
|
||||||
|
Le rectangle peut avoir un bord d'épaisseur et de couleur donnés.
|
||||||
|
Si la couleur de remplissage est '', le rectangle est "vide",
|
||||||
|
et si son épaisseur de bord n'est pas nulle, il s'affiche comme un cadre.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, dessin, x1, y1, x2, y2, couleur="black", epaisseur=0, bord="black"
|
||||||
|
):
|
||||||
|
self.dessin = dessin
|
||||||
|
self.item = dessin.canvas.create_rectangle(
|
||||||
|
x1, y1, x2, y2, fill=couleur, width=epaisseur, outline=bord
|
||||||
|
)
|
||||||
|
|
||||||
|
def couleur(self, c):
|
||||||
|
""" Changer la couleur du rectangle """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, fill=c)
|
||||||
|
|
||||||
|
def epaisseur(self, e):
|
||||||
|
""" Changer l'épaisseur du bord du rectangle """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, width=e)
|
||||||
|
|
||||||
|
def bord(self, c):
|
||||||
|
""" Changer la couleur du bord du rectangle """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, outline=c)
|
||||||
|
|
||||||
|
def position(self, x, y):
|
||||||
|
""" Changer la position du (centre du) rectangle """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
|
||||||
|
self.dessin.canvas.move(self.item, x - cx, y - cy)
|
||||||
|
|
||||||
|
def position_1(self, x, y):
|
||||||
|
""" Changer la position du premier coin du rectangle """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x, y, x2, y2)
|
||||||
|
|
||||||
|
def position_2(self, x, y):
|
||||||
|
""" Changer la position du second coin du rectangle """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1, y1, x, y)
|
||||||
|
|
||||||
|
def bouge(self, dx, dy):
|
||||||
|
""" Déplacer le rectangle de dx, dy """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.move(self.item, dx, dy)
|
||||||
|
|
||||||
|
def bouge_1(self, dx, dy):
|
||||||
|
""" Déplacer le premier coin du rectangle """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1 + dx, y1 + dy, x2, y2)
|
||||||
|
|
||||||
|
def bouge_2(self, dx, dy):
|
||||||
|
""" Déplacer le second coin du rectangle """
|
||||||
|
if self.item != None:
|
||||||
|
x1, y1, x2, y2 = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x1, y1, x2 + dx, y2 + dy)
|
||||||
|
|
||||||
|
def dessus(self):
|
||||||
|
""" Placer le rectangle au-dessus des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_raise(self.item)
|
||||||
|
|
||||||
|
def dessous(self):
|
||||||
|
""" Placer le rectangle en dessous des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_lower(self.item)
|
||||||
|
|
||||||
|
def efface(self):
|
||||||
|
""" Effacer le rectangle, qui ne peut plus alors être utilisé """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.delete(self.item)
|
||||||
|
self.item = None
|
||||||
|
|
||||||
|
|
||||||
|
# Traduire les directions cardinales en constantes Tk
|
||||||
|
tk_anchors = {
|
||||||
|
"n": tk.N,
|
||||||
|
"nord": tk.N,
|
||||||
|
"s": tk.S,
|
||||||
|
"sud": tk.S,
|
||||||
|
"e": tk.E,
|
||||||
|
"est": tk.E,
|
||||||
|
"w": tk.W,
|
||||||
|
"o": tk.W,
|
||||||
|
"ouest": tk.W,
|
||||||
|
"ne": tk.NE,
|
||||||
|
"nord-est": tk.NE,
|
||||||
|
"se": tk.SE,
|
||||||
|
"sud-est": tk.SE,
|
||||||
|
"nw": tk.NW,
|
||||||
|
"no": tk.NW,
|
||||||
|
"nord-ouest": tk.NW,
|
||||||
|
"sw": tk.SW,
|
||||||
|
"so": tk.SW,
|
||||||
|
"sud-ouest": tk.SW,
|
||||||
|
"c": tk.CENTER,
|
||||||
|
"centre": tk.CENTER,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Texte:
|
||||||
|
""" Cette classe représente un texte de position, contenu et couleur donnés.
|
||||||
|
Le texte peut aussi avoir une police et une ancre.
|
||||||
|
La police est un tuple (famille, taille, style) où famille est le nom de la police
|
||||||
|
(par exemple Times ou Helvetica), taille la taille en points, et style (optionnel)
|
||||||
|
une chaîne de caractères contenant les mots "bold", "italic", "underline", et/ou "overstrike".
|
||||||
|
L'ancre indique la position du texte par rapport à sa position.
|
||||||
|
Par défaut ('c') l'ancre est au milieu du texte.
|
||||||
|
On peut aussi indiquer un des points cardinaux ('n', 's', 'e', 'o', 'ne', 'no', 'se', 'so').
|
||||||
|
Par exemple 'so' indique que l'ancre est au coin sud-ouest du texte,
|
||||||
|
donc que le texte est au-dessus et à droite de la position x, y.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, dessin, x, y, texte, couleur="black", police=None, ancre="c"):
|
||||||
|
self.dessin = dessin
|
||||||
|
self.item = dessin.canvas.create_text(x, y, text=texte, fill=couleur)
|
||||||
|
self.police(police)
|
||||||
|
self.ancre(ancre)
|
||||||
|
|
||||||
|
def texte(self, t):
|
||||||
|
""" Changer la contenu du texte """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, text=t)
|
||||||
|
|
||||||
|
def couleur(self, c):
|
||||||
|
""" Changer la couleur du texte """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, fill=c)
|
||||||
|
|
||||||
|
def police(self, p):
|
||||||
|
""" Changer la police du texte """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, font=p)
|
||||||
|
|
||||||
|
def ancre(self, a):
|
||||||
|
""" Changer l'ancre du texte """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.itemconfigure(self.item, anchor=tk_anchors[a.lower()])
|
||||||
|
|
||||||
|
def position(self, x, y):
|
||||||
|
""" Changer la position du texte """
|
||||||
|
if self.item:
|
||||||
|
x, y = self.dessin.canvas.coords(self.item)
|
||||||
|
self.dessin.canvas.coords(self.item, x, y)
|
||||||
|
|
||||||
|
def bouge(self, dx, dy):
|
||||||
|
""" Déplacer le texte de dx, dy """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.move(self.item, dx, dy)
|
||||||
|
|
||||||
|
def dessus(self):
|
||||||
|
""" Placer le texte au-dessus des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_raise(self.item)
|
||||||
|
|
||||||
|
def dessous(self):
|
||||||
|
""" Placer le texte en dessous des autres objets """
|
||||||
|
if self.item:
|
||||||
|
self.dessin.canvas.tag_lower(self.item)
|
||||||
|
|
||||||
|
def efface(self):
|
||||||
|
""" Effacer le texte, qui ne peut plus alors être utilisé """
|
||||||
|
if self.item != None:
|
||||||
|
self.dessin.canvas.delete(self.item)
|
||||||
|
self.item = None
|
Loading…
Reference in a new issue