nsi:tds:maths:splines:hermite
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| nsi:tds:maths:splines:hermite [2023/01/21 19:11] – goupillwiki | nsi:tds:maths:splines:hermite [2023/01/22 19:29] (Version actuelle) – goupillwiki | ||
|---|---|---|---|
| Ligne 29: | Ligne 29: | ||
| * $c_0 = P_0$ ; | * $c_0 = P_0$ ; | ||
| * $c_1 = v_0$ ; | * $c_1 = v_0$ ; | ||
| - | * $c_2 = 3(P_1 - P_0) + v_2 - 2v_0$ ; | + | * $c_2 = 3(P_1 - P_0) - v_1 - 2v_0$ ; |
| * $c_3 = v_0 + v_1 + 2(P_0 - P_1)$. | * $c_3 = v_0 + v_1 + 2(P_0 - P_1)$. | ||
| + | |||
| + | ===== Quoi faire ? ===== | ||
| + | |||
| + | Une courbe de Bézier interviendrait dans un projet. Par exemple un jeu Pygame ou un logiciel de dessin. | ||
| + | |||
| + | Nous allons commencer par concevoir tous les outils pour calculer les coordonnées des points d'une courbe de Bezier puis nous allons l' | ||
| + | |||
| + | ===== Implémentation ===== | ||
| + | |||
| + | On souhaite faire une implémentation semblable à celle faite dans la fiche [[nsi: | ||
| + | |||
| + | ==== Une classe Point ==== | ||
| + | |||
| + | On reprend la classe '' | ||
| + | |||
| + | <WRAP important> | ||
| + | La classe '' | ||
| + | </ | ||
| + | |||
| + | ==== Les données fournies ==== | ||
| + | |||
| + | Pour produire la spline de Hermite, on devra lui fournir une liste de paires '' | ||
| + | |||
| + | Exemple : | ||
| + | <code python> | ||
| + | pts = [(10,50), (200, 400), (300, 300), (500, 200)] | ||
| + | vecteurs = [(50,20), (60, -10), (10, -50), (30,0)] | ||
| + | </ | ||
| + | |||
| + | ==== Une classe Hermite ==== | ||
| + | |||
| + | Cette classe aura la responsabilité des calculs liés à la spline de Hermite. | ||
| + | |||
| + | Ajoutez le module suivant à votre projet et complétez les fonctions. | ||
| + | |||
| + | <code python> | ||
| + | # hermite.py | ||
| + | |||
| + | from point import Point | ||
| + | |||
| + | class Hermite: | ||
| + | def __init__(self, | ||
| + | ''' | ||
| + | pts: liste de paires (x,y) représentant les points | ||
| + | vecteurs: liste de paires (x,y) représentant les vecteurs | ||
| + | ''' | ||
| + | assert len(pts) >= 2, "Il faut au moins deux points dans la spline." | ||
| + | assert len(pts) == len(vecteurs), | ||
| + | self.points = [Point(x,y) for x,y in pts] | ||
| + | self.vecteurs = [Point(x,y) for x,y in vecteurs] | ||
| + | | ||
| + | def calc_coeffs(self, | ||
| + | ''' | ||
| + | i:indice de l'arc considéré | ||
| + | la courbe de Bézier est calculée avec les points P0, P1, P2, P3 de l'arc | ||
| + | on calcule 4 coefficients : | ||
| + | c0 = P0 | ||
| + | c1 = v0 | ||
| + | c2 = 3(P1 - P0) -v1 -2v0 | ||
| + | c3 = v0 + v2 + 2(P0 - P1) | ||
| + | La fonction renvoie c0, c1, c2, c3 | ||
| + | remarque: chaque coefficient est de type Point. | ||
| + | ''' | ||
| + | # vérifie que i est bien une valeur valide : 0 <= i <= n-2 | ||
| + | # récupérer les P0 et P1 aux rangs i et i+1 dans les points | ||
| + | # récupérer les v0 et v1 aux rangs i et i+1 dans les vecteurs | ||
| + | # calculer les coefficients et les renvoie | ||
| + | | ||
| + | def M(self, t:float, i:int): | ||
| + | ''' | ||
| + | t: flottant entre 0 et 1, compris | ||
| + | i: rang de l'arc considéré | ||
| + | renvoie c0 + c1*t + c2*t**2 + c3*t**3 avec c0, c1, c2, c3 | ||
| + | les coeffs de la fonction précédente. | ||
| + | ''' | ||
| + | # obtenir les valeurs des coefficients | ||
| + | # renvoie le résultat du calcul | ||
| + | | ||
| + | def tangent(self, | ||
| + | t: flottant entre 0 et 1, compris | ||
| + | i: rang de l'arc considéré | ||
| + | renvoie c1 + 2*c2*t + 3*c3*t**2 avec c0, c1, c2, c3 | ||
| + | ''' | ||
| + | # obtenir les valeurs des coefficients | ||
| + | # renvoie le résultat du calcul | ||
| + | | ||
| + | def plot_points(self, | ||
| + | ''' | ||
| + | renvoie la liste des points (type Point) constituant la courbe. | ||
| + | N représente le nombre de points à calculer pour chaque arc. | ||
| + | ''' | ||
| + | # préparer une liste vide | ||
| + | # pour chaque arc i, | ||
| + | # pour chaque t allant de 0/N à (N-1)/N | ||
| + | # calculer M(t, i) et l' | ||
| + | # compléter la liste avec une copie du dernier point de self.points | ||
| + | # renvoyer la liste | ||
| + | </ | ||
| + | |||
| + | <WRAP tip> | ||
| + | Lors de l' | ||
| + | </ | ||
| + | |||
| + | ==== Utilisation avec matplotlib ==== | ||
| + | |||
| + | On se propose d' | ||
| + | |||
| + | <code python> | ||
| + | # demohermite.py | ||
| + | # démonstration en utilisant matplotlib | ||
| + | |||
| + | import matplotlib.pyplot as plt | ||
| + | from hermite import Hermite | ||
| + | |||
| + | pts = [(10,50), (200, 400), (300, 300), (500, 200)] | ||
| + | vecteurs = [(50,20), (60, -10), (10, -50), (30,0)] | ||
| + | |||
| + | spline = Hermite(pts, | ||
| + | |||
| + | # tracé de la courbe | ||
| + | plot_pts = spline .plot_points() | ||
| + | # dans matplotlib, il faut placer les x et les y dans deux listes séparées | ||
| + | x = [pt.x for pt in plot_pts ] | ||
| + | y = [pt.y for pt in plot_pts ] | ||
| + | plt.plot(x, y) | ||
| + | |||
| + | # tracé des points : | ||
| + | x = [x for x,y in pts] | ||
| + | y = [y for x,y in pts] | ||
| + | plt.scatter(x, | ||
| + | |||
| + | plt.show() | ||
| + | </ | ||
nsi/tds/maths/splines/hermite.1674324708.txt.gz · Dernière modification : de goupillwiki
