Objectif de la fiche : utiliser un langage de programmation pour étudier la relation approchée entre la variation du vecteur vitesse d'un système modélisé par un point matériel entre deux instants voisins, et la somme des forces appliquées sur celui-ci.
Cette fiche est autonome : tu n'as besoin d'aucun autre document, les coordonnées obtenues par pointage vidéo sont recopiées directement dans le script. Chaque étape contient un script incomplet à compléter, puis à copier-coller dans Thonny (ou dans la console Basthon tout en bas de la page si tu n'as pas Thonny sous la main).
Les données du pointage
- Un logiciel de pointage vidéo a permis de relever les coordonnées
(x, y)d'une balle de golf en vol, image par image, sur une chronophotographie. - L'intervalle de temps entre deux images est constant :
0,10 s. Le tableau des instants n'a donc pas besoin d'être saisi à la main : il se déduit directement du nombre de points pointés, avec0.1*np.arange(len(x)). - Le script ci-dessous est déjà complet : copie-le tel quel dans Thonny (ou dans Basthon) pour commencer.
import numpy as np
import matplotlib.pyplot as plt
# Coordonnées pointées de la balle de golf (m)
x = np.array([0.01, 0.41, 0.91, 1.39, 1.86, 2.33, 2.81, 3.33, 3.79, 4.31, 4.83, 5.36, 5.86, 6.34, 6.77])
y = np.array([0.01, 0.52, 0.81, 1.42, 1.77, 2.02, 2.16, 2.19, 2.13, 1.96, 1.71, 1.38, 0.97, 0.50, 0])
# Instants associés, générés automatiquement (0,10 s entre deux images)
t = 0.1 * np.arange(len(x))
Visualiser la trajectoire
- Trace
yen fonction dex, avec des points bleus reliés par une ligne ('bo-'). - Ajoute les étiquettes
"xreelle"/"yreelle"et une grille.
# TODO : trace y en fonction de x, points bleus reliés
plt.plot(__, __, '____')
plt.xlabel("________")
plt.ylabel("________")
plt.grid()
plt.show()
Une arche régulière : la balle monte, atteint un sommet vers x ≈ 3,3 m, y ≈ 2,19 m, puis redescend jusqu'à toucher le sol vers x ≈ 6,8 m — la silhouette caractéristique d'une trajectoire parabolique.
Construire les vecteurs vitesse
- La vitesse horizontale au point
is'estime par différence centrée :vx = (x[i+2] - x[i]) / (t[i+2] - t[i]). Cette formule utilise le point avant et le point après le pointi+1, ce qui donne une estimation plus précise qu'une différence simple. - Comme le calcul utilise
x[i+2], il est impossible de l'appliquer aux deux derniers points de la liste : la boucle doit donc parcourirm = np.arange(len(t)-2), et nonlen(t)directement. - Crée deux listes vides
vxletvyl, puis remplis-les avec une bouclefor, comme dans les fiches précédentes.
vxl = []
m = np.arange(len(t) - _)
for i in m :
vx = (x[i+_] - x[_]) / (t[i+_] - t[_])
vxl.append(__)
vyl = []
m = np.arange(len(t) - _)
for i in m :
vy = (y[i+_] - y[_]) / (t[i+_] - t[_])
vyl.append(__)
Indice
Ici, l'intervalle de temps entre t[i] et t[i+2] vaut toujours 0,2 s (deux pas de 0,1 s) : la division par (t[i+2]-t[i]) reste donc valable même si, dans d'autres contextes, les instants ne sont pas régulièrement espacés.
vxl et vyl contiennent chacune 13 valeurs (15 points de départ, moins 2). vxl[i] correspond en réalité à la vitesse horizontale au point i+1 — un décalage d'indice dont il faudra se souvenir pour la suite.
Construire les vecteurs accélération
- Exactement la même démarche permet de calculer la variation de vitesse par unité de temps (l'accélération), mais cette fois à partir des listes
vxletvylplutôt quexety. - Comme
vxletvylont déjà 2 valeurs de moins quexety, et que le calcul utilise encore un décalage de 2, la boucle doit cette fois parcourirm = np.arange(len(t)-4).
axl = []
m = np.arange(len(t) - _)
for i in m :
ax = (vxl[i+_] - vxl[_]) / (t[i+_] - t[_])
axl.append(__)
ayl = []
m = np.arange(len(t) - _)
for i in m :
ay = (vyl[i+_] - vyl[_]) / (t[i+_] - t[_])
ayl.append(__)
Indice
Le décalage s'accumule : axl[i] correspond à l'accélération horizontale au point i+2 de la trajectoire d'origine (un décalage de 1 par rapport à vxl, qui était lui-même décalé de 1 par rapport à x).
axl et ayl contiennent chacune 11 valeurs. C'est ayl, l'accélération verticale, qui va nous intéresser pour la suite : c'est elle qui devrait se rapprocher de -9,8 m·s⁻², la valeur du champ de pesanteur.
Représenter les vecteurs accélération
- Pour chaque point où l'accélération a pu être calculée, trace deux flèches avec
plt.arrow, toutes deux partant de(x[i+2], y[i+2])— le décalage d'indice repéré à l'étape précédente : la boucle doit donc démarrer à1avecm = np.arange(1, len(t)-4), pour rester valide. - La première flèche représente l'accélération réellement mesurée :
plt.arrow(x[i+2], y[i+2], 0.1*axl[i], 0.1*ayl[i], head_width=0.1). Le facteur0.1est purement esthétique, pour que les flèches restent lisibles sur le graphe. - La seconde flèche, en rouge (
fc='r', ec='r'), sert de référence : elle est purement verticale, de norme0.1*9.8— le champ de pesanteur tabulé, à la même échelle. - Superpose ces flèches à la trajectoire (reprends le tracé de l'étape 1), avec
plt.xlim(0,7),plt.ylim(0,3)et le titre"Comparaison entre accélération et champ de pesanteur".
m = np.arange(1, len(t) - _)
for i in m :
plt.arrow(x[i+_], y[i+_], 0.1*axl[_], 0.1*ayl[_], head_width=0.1)
plt.arrow(x[i+_], y[i+_], 0*axl[i], 0.1*(0*axl[i]-___), fc='_', ec='_', head_width=0.1)
plt.xlim(_, _)
plt.ylim(_, _)
plt.grid()
plt.plot(x, y, '____')
plt.xlabel("________")
plt.ylabel("________")
plt.title("_______________________________________________")
plt.show()
Le long de la parabole, deux jeux de flèches quasiment superposés : les flèches noires (accélération mesurée) pointent presque toutes verticalement vers le bas, avec une longueur très proche de celle des flèches rouges (référence à 9,8 m·s⁻²). Conclusion visuelle : les variations du vecteur vitesse sont, pour l'essentiel, verticales et dirigées vers le bas.
Comparaison quantitative à g
- Pour aller au-delà de la comparaison visuelle, trace
ayl(l'accélération verticale réelle) en fonction du numéro de point, sur un graphe dédié. - Superpose deux droites horizontales : l'une d'ordonnée constante
-9,8(le champ de pesanteur théorique), l'autre d'ordonnée égale à la moyenne des valeurs deayl. - Cette moyenne s'obtient élégamment avec
np.polyfit(m, ayl, 0): un polynôme de degré 0 (une constante) qui « modélise au mieux » un nuage de points n'est autre que leur moyenne.
m = np.arange(0, len(t) - _)
ath = 0*m - ___
# TODO : modélise ayl par une constante (polynôme de degré 0)
mod = np.polyfit(_, ___, _)
moda = 0*m + mod[_]
plt.plot(m, ayl, '____', label="______")
plt.grid()
plt.ylim(-20, 0)
plt.plot(m, ath, '__', label="_")
plt.plot(m, moda, '__', label="______")
plt.xlabel("__________________")
plt.ylabel("________________________")
plt.title("_______________________________________________")
plt.show()
print(round(mod[_], 1))
Indice
np.polyfit(m, ayl, 0) renvoie un tableau avec une seule valeur, mod[0] : c'est cette valeur — la moyenne — qu'il faut réutiliser pour construire la droite moda et pour l'afficher à la fin.
La console affiche -8.5 : la moyenne des accélérations verticales mesurées vaut environ -8,5 m·s⁻², proche de la valeur théorique -9,8 m·s⁻² sans lui être rigoureusement égale. L'écart s'explique par la précision limitée du pointage vidéo — un rappel utile que toute mesure expérimentale s'accompagne d'une incertitude.
Pense-bête — différences centrées et décalages d'indices
| (x[i+2]-x[i])/(t[i+2]-t[i]) | différence centrée : plus précise qu'une différence simple |
| vxl[i] | correspond en réalité au point i+1 |
| axl[i] | correspond en réalité au point i+2 |
| np.polyfit(x,y,0) | modélise par une constante = la moyenne |
| 0.1 * | facteur d'échelle pour la lisibilité des vecteurs |
| g ≈ 9,8 m·s⁻² | champ de pesanteur terrestre |
Pas de Thonny sous la main ? Utilise Basthon
Ouvrir dans un nouvel onglet ↗Ctrl+V ou Cmd+V) le code copié avec les boutons « Copier le code » ci-dessus, puis appuie sur Entrée pour l'exécuter.