You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
10 KiB
279 lines
10 KiB
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
|
|
# k l m
|
|
|
|
#################################################################################################
|
|
###
|
|
### EXERCICE 2 : Définir une nouvelle police de caractères sous Python
|
|
###
|
|
#################################################################################################
|
|
|
|
|
|
# On active le "mode interactif" de pyplot. Ainsi, les plt.show() ne sont plus nécessaires.
|
|
plt.ion()
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Fonction de "fin temporaire" pendant l'avancée du TP. Attend une frappe Entrée, puis quitte le script.
|
|
|
|
def stop_ici():
|
|
plt.pause(0.1) # nécessaire pour que matplotlib ait le temps d'afficher les figures
|
|
input()
|
|
exit()
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Tous les passages indiqués "TODO()" sont à remplacer par vos soins
|
|
|
|
def TODO():
|
|
print("à vous!")
|
|
stop_ici()
|
|
|
|
|
|
######################################################################
|
|
### Fonctions de tracé de courbes de Bézier : reprises du TP2
|
|
######################################################################
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Calcul d'un point d'une courbe de Bézier
|
|
#
|
|
# - t = paramètre du point de la courbe à calculer [nombre réel entre 0 et 1]
|
|
# - P = points de contrôle [au même format qu'au TP2 : np.array de taille (N+1,2)]
|
|
|
|
def bezierCasteljau(t,P):
|
|
while(P.shape[0]>1):
|
|
P = (1-t)*P[:-1] + t*P[1:]
|
|
return P[0]
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Traçage d'une courbe dans sa totalité
|
|
#
|
|
# - P = points de contrôle [au même format qu'au TP2 : np.array de taille (N+1,2)]
|
|
# - trace_controle = True pour tracer également le polygone de controle
|
|
# - kwargs permet de passer tous les arguments habituels de la commande plt.plot (couleur, markers, etc.)
|
|
|
|
def traceBezier(P, trace_controle=False, **kwargs):
|
|
if trace_controle:
|
|
plt.plot( P[:,0], P[:,1], linestyle='--', color='black')
|
|
Nt = 100
|
|
Ft = np.array( [ bezierCasteljau(t,P) for t in np.linspace(0,1,Nt) ] )
|
|
plt.plot( Ft[:,0], Ft[:,1], **kwargs)
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Traçage d'un carré de coté 1
|
|
#
|
|
# - offset = coordonnées du coin en bas à gauche du carré ([0,0] par défaut)
|
|
# - kwargs permet de passer tous les arguments habituels de la commande plt.plot (couleur, markers, etc.)
|
|
|
|
def traceCarre(offset=[0,0], **kwargs):
|
|
Carre = np.array( [ [0,0], [1,0], [1,1], [0,1], [0,0] ] )
|
|
Carre = Carre + np.array(offset)
|
|
plt.plot( Carre[:,0], Carre[:,1], **kwargs)
|
|
|
|
|
|
print("-"*80)
|
|
print(''' QUESTION 1 : Prise en main des fonctions.
|
|
|
|
Dans une première figure, tracez :
|
|
- En VERT: un carré de coté 1 (et tel que son coin en bas à gauche soit aux coordonnées [0,0])
|
|
- En BLEU: la courbe de Bézier associée aux points de contrôle
|
|
P0=[0,0], P1=[2,2], P2=[2,-2], P3=[0,2], P4=[0,0]
|
|
''')
|
|
|
|
|
|
|
|
plt.figure()
|
|
plt.title("Question 1")
|
|
|
|
traceCarre(offset=[0,0], color='green')
|
|
P = np.array( [ [0,0], [2,2], [2,-2], [0,2], [0,0] ] )
|
|
traceBezier(P, color='blue')
|
|
|
|
plt.axis('equal')
|
|
|
|
# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
|
|
|
|
|
|
print("-"*80)
|
|
print(''' QUESTION 2.
|
|
Complétez le code de tracé de la fonction traceLettre ci-dessous [le TODO() à la fin de la fonction].
|
|
|
|
Pour ce faire, réfléchissez bien aux points suivants :
|
|
- Sous quel format la fonction traceBezier doit-elle recevoir les points de contrôle ?
|
|
- Comment 'transmettre' à la fonction traceBezier le fait qu'on veut ou non tracer le polygone de contrôle ?
|
|
- Comment 'transmettre' à la fonction traceBezier les options de traçage (couleur, etc.) passées à la fonction traceLettres ?
|
|
|
|
Vérification : une fois le TODO() complété, le code de test suivant devra tracer la lettre "a" en bleu (et ses points de controle)
|
|
''')
|
|
|
|
|
|
###################################################################
|
|
# Fonction de tracé d'une lettre quelconque.
|
|
# C'est la fonction principale de cet exercice.
|
|
# On vous donne un squelette, que vous allez compléter progressivement.
|
|
###################################################################
|
|
#
|
|
# - char : caractère qu'on souhaite tracer ("a", "b", etc., ainsi que l'espace " ")
|
|
# - offset = coordonnées du point auquel on souhaite tracer la lettre ([0,0] si on ne précise pas)
|
|
# - trace_controle, kwargs : même signification que pour la fonction traceBezier
|
|
|
|
def traceLettre(char, offset=[0,0], trace_controle=False, **kwargs):
|
|
|
|
# Définition de la liste des points de contrôle pour cette lettre
|
|
# ( strokes[0]=points de contrôle pour le 1er trait, strokes[1]=points de contrôle pour le 2è trait, etc. )
|
|
strokes = []
|
|
|
|
if char =="a":
|
|
strokes.append( [ [.8,.05], [.8,1] , [.75,1.1], [.1,.85] ] ) # premier trait du 'a'
|
|
strokes.append( [ [.78,.1], [-.25,-.3], [-.3,.7], [.8, .5] ] ) # deuxième trait du 'a'
|
|
|
|
elif char=="m":
|
|
strokes.append( [ [0.5,0], [0.5,0.8], [0,0.8], [0,0] ] )
|
|
strokes.append( [ [0.5,0], [0.5,0.8], [1,0.8], [1,0] ] )
|
|
# B = np.array([[4.3,1.4], [4.3,1.2]]) # Permet de faire un bout de sein si on inverse les appends de [A B C D] en [B A D C]
|
|
# plt.plot(B[:,0], B[:,1], linestyle='--', color='black')
|
|
|
|
elif char=="k":
|
|
strokes.append( [ [0.2,0], [0.2,1]] )
|
|
strokes.append( [ [0.2,0.3], [0.5,0]] )
|
|
strokes.append( [ [0.2, 0.3], [0.5,0.3], [0.5,0.7], [0.2,0.7]])
|
|
|
|
elif char=="l":
|
|
strokes.append( [ [0.2,0.5], [0.3,0.5], [0.3,1], [0.2,1] ] )
|
|
strokes.append([ [0.2, 0], [0.2, 1] ])
|
|
|
|
elif char==" ":
|
|
pass # pour 'tracer' le caractère espace... on ne trace rien ! ^^
|
|
|
|
else:
|
|
raise("character '"+char+"' is not implemented yet")
|
|
|
|
### Le tracé proprement dit
|
|
for lst in strokes:
|
|
print(lst) # pour que vous compreniez ce que contient la variable lst (vous pouvez ensuite supprimer cette ligne)
|
|
P = np.array(lst)
|
|
traceBezier(P + offset) # Tracer la courbe de Bézier définie par la liste de points lst
|
|
|
|
|
|
|
|
### Code de test:
|
|
plt.figure()
|
|
traceLettre("a", trace_controle=True, color="blue", linewidth=3)
|
|
# traceCarre(color="green")
|
|
plt.axis("equal")
|
|
|
|
# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
|
|
|
|
|
|
print("-"*80)
|
|
print(''' QUESTION 3 : trois nouvelles lettres.
|
|
|
|
À ce stade, la fonction traceLettre sait uniquement tracer un "a". Rajoutez le code (=les 'strokes') permettant de tracer les lettres "g", "t" et "c".
|
|
|
|
Méthode conseillée : construisez la lettre sous inkscape (exo 1), puis relevez la position des points de contrôle et rentrez-les sous Python.
|
|
|
|
Attention : chaque lettre doit "tenir" dans un carré unité (le "g" pouvant dépasser un peu vers le bas, et le "t" un peu vers le haut)
|
|
''')
|
|
|
|
### Teste le "g":
|
|
plt.figure()
|
|
traceLettre("m", trace_controle=True, color="blue", linewidth=3)
|
|
traceCarre(color="green")
|
|
plt.axis("equal")
|
|
|
|
# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
|
|
|
|
### Teste le "t":
|
|
plt.figure()
|
|
traceLettre("k", trace_controle=True, color="blue", linewidth=3)
|
|
traceCarre(color="green")
|
|
plt.axis("equal")
|
|
|
|
# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
|
|
|
|
### Teste le "c":
|
|
plt.figure()
|
|
traceLettre("l", trace_controle=True, color="blue", linewidth=3)
|
|
traceCarre(color="green")
|
|
plt.axis("equal")
|
|
|
|
# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
|
|
|
|
|
|
print("-"*80)
|
|
print(''' QUESTION 4 : Gestion de l'offset.
|
|
|
|
Modifiez votre fonction traceLettre afin de pouvoir passer en option l'OFFSET (=décalage) auquel on souhaite tracer la lettre.
|
|
Inspirez-vous de la fonction traceCarre, pour laquelle cette fonctionnalité est déjà implémentée.
|
|
|
|
Vérification : une fois votre code écrit, le code ci-dessous représentera les 4 lettres a,c,g,t dans la disposition suivante:
|
|
ac
|
|
gt
|
|
''')
|
|
|
|
### Vérification:
|
|
plt.figure()
|
|
traceLettre("a", offset = [0,0], color="blue", linewidth=3)
|
|
traceCarre(color="green", offset=[0,0] )
|
|
traceLettre("m", offset = [2,0], color="blue", linewidth=3)
|
|
traceCarre(color="green", offset=[2,0] )
|
|
traceLettre("l", offset = [0,-2], color="blue", linewidth=3)
|
|
traceCarre(color="green", offset=[0,-2] )
|
|
traceLettre("k", offset = [2,-2], color="blue", linewidth=3)
|
|
traceCarre(color="green", offset=[2,-2] )
|
|
plt.axis("equal")
|
|
|
|
# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
|
|
|
|
|
|
print("-"*80)
|
|
print(''' QUESTION 5.
|
|
Répartissez-vous le travail dans le groupe TP afin de coder TOUTES les lettres de l'alphabet !
|
|
(Il faudra donc vous "passer" le code de chaque lettre les uns aux autres, au fur et à mesure que vous les écrivez.)
|
|
|
|
Attention : chaque lettre doit toujours tenir dans un carré unité (en dépassant un peu vers le haut ou le bas pour certaines lettres comme le "l", le "j", etc.).
|
|
''')
|
|
|
|
### Vérification (par exemple, pour vérifier le code du "b" une fois qu'il est défini):
|
|
plt.figure()
|
|
traceLettre("a", trace_controle=True, color="blue", linewidth=3)
|
|
traceCarre(color="green")
|
|
plt.axis("equal")
|
|
|
|
# stop_ici() # -------------- Supprimez cette ligne pour passer à la suite --------------
|
|
|
|
|
|
print("-"*80)
|
|
print(''' QUESTION 6 : tracé d'une phrase quelconque.
|
|
|
|
Écrivez une fonction traceStr, avec le prototype défini ci-dessous, qui trace une chaîne de caractères quelconque (sans ponctuation) dans votre police.
|
|
|
|
Consigne pour le OFFSET (décalage) : chaque caractère de la chaîne doit être tracé avec un décalage de +1 vers la droite par rapport au caractère précédent.
|
|
''')
|
|
|
|
# --------------------------------------------------------------------------------------
|
|
# Fonction de tracé d'une chaîne de caractères quelconque (sans ponctuation)
|
|
#
|
|
# - chaine = chaîne de caractères qu'on souhaite tracer
|
|
# - trace_controle et kwargs : même signification que pour la fonction traceBezier
|
|
|
|
def traceStr(chaine, trace_controle=False, **kwargs):
|
|
offset = [0,0]
|
|
for char in chaine:
|
|
traceLettre(char, trace_controle=trace_controle, offset=offset, **kwargs)
|
|
offset[0] += 1
|
|
|
|
|
|
### Vérification:
|
|
|
|
phrase = "ammm aallkka ammllkklmm" # version basique avec uniquement les lettre a,c,g,t
|
|
# phrase = "portez ce vieux whisky au juge blond qui fume" # pangramme (phrase avec les 26 lettres de l'alphabet)
|
|
|
|
plt.figure()
|
|
traceStr(phrase, color="blue", linewidth=3)
|
|
plt.axis("equal")
|
|
|
|
|
|
|
|
stop_ici() # FINI !
|