Algo & Prog 1 Python : TP séance 08
- Rendu du TP sur Ametice :
- Suivez les instructions pour le rendu du TP en mettant le bon numéro de séance dans le nom du répertoire.
- N'oubliez pas de rendre votre travail à la fin de la séance comme indiqué, même si vous n'avez pas fini la planche de TP, puis de rendre la version finale avant le début de la séance suivante.
Exercice 1 : translation de polygone et distance à un segment
Recopiez dans votre répertoire de travail les modules sommet.py
, polygone.py
et app.py
du TP précédent. Il est par conséquent indispensable de l'avoir
terminé pour aborder cette planche.
1.a. Distance à une droite
Soit trois points \(A\), \(B\), \(C\), on veut calculer la distance \(h\) du point \(A\) à la droite \((B,C)\).
Pour la calculer, on considère le parallélogramme \(P\) de base \((B,C)\) dont un des sommets opposés est \(A\). On a :
- aire(P) = \(||BC|| \times h\) ;
- on a aussi : aire(P) = \(|\text{det}(\vec{BC}, \vec{BA})|\)
Donc si B et C sont distinct on a \(h\) = \(|\text{det}(\vec{BC}, \vec{BA})| \,/\, ||BC||\)
si B et C sont confondus, alors on pose \(h\) = ||AB|| = \(\sqrt{(x_B-x_A)^2+(y_B-y_A)^2}\).
Dans la classe Polygone
, rajouter une méthode calculer_distance_droite
recevant en paramètre les coordonnées xA, yA, xB, yB, xC, yC
des trois points.
La méthode calcule et renvoie la distance de \(A\) à la droite \((B,C)\).
1.b. Distance à un segment
Avec les mêmes notations que dans la question précédente, on veut maintenant calculer la distance \(e\) de \(A\) au segment \([B,C]\).
On pose \(t = \sqrt{||BC||^2+h^2}\), qui est la longueur de la diagonale du rectangle de base \([B,C\)] et de hauteur \(h\). Le sommet \(A\) est sur le côté opposé du rectangle si le maximum de \(||AB||\) et \(||AC||\) est inférieur ou égal à \(t\). Dans ce cas, la distance \(e\) est égale à \(h\) ; sinon, \(e\) est le minimum de \(||AB||\) et \(||AC||\).
Dans la classe Polygone
, rajouter une méthode calculer_distance_segment
recevant en paramètre les coordonnées xA, yA, xB, yB, xC, yC
des trois points.
La méthode calcule et renvoie la distance de \(A\) au segment \([B,C]\).
1.c. Déplacement du polygone
Nous donnons maintenant la possibilité de déplacer tout le polygone en cliquant sur un segment (ou à proximité immédiate) puis en tirant la souris. Le traitement lorsque la souris est pressée devient :
- si un sommet est cliqué, on déplacera le sommet,
- sinon, si un segment est cliqué, on déplacera tout le polygone,
- sinon on insère un sommet, qui pourra être déplacé en tirant la souris.
Dans la classe Polygone
, rajouter une méthode
trouver_segment_clique
qui reçoit les coordonnées de la souris e_x, ev_y
,
puis cherche parmi les segments du polygone ouvert polyg1
,
le segment \([S_k,S_{k+1}]\) constitué par les sommets d'indice \(k\) et \(k+1\),
dont la souris est le plus proche.
Si la distance minimale obtenue est inférieure à un seuil fixé à 6.0
alors
on renvoie \(k\), sinon on renvoie -1
.
Dans la méthode creer_donnees
de la classe App
mémoriser l'attribut
numero_segment_clique
à la valeur -1
.
Dans la méthode on_button1_press
de App
, si aucun sommet n'est cliqué,
rechercher le numéro de segment cliqué et le mémoriser dans l'attribut
numero_segment_clique
; s'il n'y a ni sommet ni segment cliqué alors
on insère un nouveau sommet.
Dans la méthode on_button1_motion
, si un segment est cliqué, déplacer
tout le polygone, en translatant chaque sommet du vecteur déplacement
entre la précédente position de la souris et la position actuelle,
puis tout redessiner.
Pour faire les translations il faut donc mémoriser les coordonnées de la souris
dans des attributs (par exemple clic_x
et clic_y
) dans on_button1_press
,
et les mettre à jour à la fin de on_button1_motion
.
Enfin dans on_button1_release
, remettre systématiquement
numero_segment_clique
à -1
.
Exercice 2. Algorithmes géométriques sur le polygone
2.a. Boîte englobante
La boîte englobante d'une liste de sommets est le plus petit rectangle parallèle aux axes qui contient tous les sommets. Pour déterminer les coordonnées de la boîte englobante il suffit donc de chercher le min et le max en \(x\) et en \(y\) des coordonnées des sommets.
Rajouter dans la classe Polygone
une méthode dessiner_boite_englobante
qui dessine en vert la boîte englobante des sommets de polyg1
.
Appeler la méthode au début de dessiner_tout
dans la classe App
.
2.b. Tri des sommets
Rajouter dans la classe Polygone
une méthode trier_sommets
, qui
reçoit en paramètre un critère de tri sous la forme d'une chaîne de
caractères critere
.
Si le critère est x+
, alors la méthode trie les sommets du polygone
par ordre croissant pour les coordonnées x
à l'aide d'une lambda ;
idem pour x-
dans le sens décroissant.
De même pour y+
et y-
.
On rajoute encore le cas x+y
pour un tri croissant sur les coordonnées
x+y
.
À la fin du tri, la méthode renomme tous les sommets en partant de 0
.
Dans la classe App
, rajouter 5 boutons qui déclenchent le tri correspondant
puis appellent dessiner_tout
.