109 lines
3.8 KiB
Python
109 lines
3.8 KiB
Python
# coding: utf-8
|
|
# La ligne précédente est indispensable pour accpeter les accents dans le fichier
|
|
|
|
# Importe les modules qui seront nécessaires
|
|
import math # Fonctions mathématiques : math.cos, math.sin, math.pi, etc
|
|
import random # Générateurs de nombres aléatoires
|
|
import numpy # Calcul numérique sur des vecteurs, matrices, etc
|
|
|
|
# Importe le fichier graphique.py qui
|
|
import graphique
|
|
|
|
class Sommet:
|
|
'''Classe représentant un sommet d'un polygone'''
|
|
|
|
def __init__(self, theta, r):
|
|
'''Constructeur de la classe Sommet : (theta,r) sont les coordonnées polaires du sommet self'''
|
|
self.deplace(theta, r)
|
|
|
|
def deplace(self, theta, r):
|
|
'''Déplace le sommet self: (theta,r) sont les nouvelles coordonnées polaires'''
|
|
|
|
# Sauvegarde les coordonnées polaires dans des attributs de l'objet self
|
|
self.theta = theta
|
|
self.r = r
|
|
|
|
# Calcule les coordonnées cartésiennes (pour l'affichage)
|
|
# On utilise la bibliothèque de calcul numérique numpy.
|
|
self.pos = numpy.array([math.cos(theta), math.sin(theta)]) * r
|
|
|
|
def __str__(self):
|
|
'''Fonction spéciale de conversion en chaîne de caractères'''
|
|
|
|
chaine = '({:0.2f},{:0.2f})'.format(self.pos[0], self.pos[1])
|
|
return chaine
|
|
|
|
class Polygone:
|
|
''' Classe représentant un polygone du plan'''
|
|
|
|
def __init__(self, n, R):
|
|
'''Constructeur d'un objet Polygone : crée un polygone régulier
|
|
à n sommets placés sur le cercle de rayon R centré sur l'origine'''
|
|
|
|
# Vérifie que les arguments ont le type attendu
|
|
assert isinstance(n, int)
|
|
assert isinstance(R, float)
|
|
|
|
# Crée comme attribut de self une liste pour accueillir les sommets
|
|
self.sommets = []
|
|
|
|
# Crée un attribut pour stocker le nom du polygone
|
|
self.nom = str(n) + "-polygone régulier"
|
|
|
|
# Remplie la liste des n sommets
|
|
alpha = 2. * math.pi / n
|
|
angle = math.pi / 2.
|
|
for _ in range(n):
|
|
self.sommets.append(Sommet(angle, R))
|
|
angle += alpha
|
|
|
|
def __str__(self):
|
|
'''Fonction spéciale de conversion en chaîne de caractères'''
|
|
chaine = self.nom + ' = ('
|
|
if(len(self.sommets) > 0):
|
|
chaine += str(self.sommets[0])
|
|
for s in self.sommets[1:]:
|
|
chaine += ', ' + str(s)
|
|
chaine += ')'
|
|
return chaine
|
|
|
|
def secoue(self, amplitudeAngulaire, amplitudeRadiale):
|
|
'''Fonction qui déplace aléatoirement chaque sommet selon une amplitude angulaire et radiale réglable'''
|
|
|
|
# Modifie les coordonnées de chaque sommet à l'aide de la méthode deplace
|
|
for s in self.sommets:
|
|
s.deplace(
|
|
s.theta + (random.random() * 2. - 1.) * amplitudeAngulaire,
|
|
s.r * (1. + (random.random() * 2. - 1.) * amplitudeRadiale)
|
|
)
|
|
|
|
# Change le nom du polygone
|
|
self.nom = str(len(self.sommets)) + "-polygone secoué"
|
|
|
|
|
|
def trace(self, afficheur):
|
|
'''Fonction de dessin'''
|
|
|
|
assert isinstance(afficheur, graphique.Afficheur)
|
|
|
|
afficheur.renomme(self.nom)
|
|
precedent = self.sommets[-1]
|
|
afficheur.changeCouleur((0.,0.,0.))
|
|
|
|
for suivant in self.sommets:
|
|
afficheur.traceLigne(precedent.pos, suivant.pos)
|
|
precedent = suivant
|
|
|
|
afficheur.changeCouleur((1.,0.,0.))
|
|
for sommet in self.sommets:
|
|
afficheur.tracePoint(sommet.pos)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
triangle = Polygone(3, 10.)
|
|
print(triangle)
|
|
graphique.affiche(triangle, (0., 0.), 10., blocage = False)
|
|
|
|
heptagone = Polygone(7, 10.)
|
|
heptagone.secoue(math.pi / 5, 0.1)
|
|
graphique.affiche(heptagone, (0., 0.), 10.)
|