Retour à l'accueil Contact : etienne"at"les-sauvages.fr ->

Simulateur physique : principes

Je propose donc de coder un petit simulateur physique, vite fait t'as vu, juste pour le plaisir de se prendre la tête avec des maths cheloues et des concepts physiques qui feraient marrer un astrophysicien.

On va coder en C++ sous Qt Creator, parce que c'est le plus facile à mettre en oeuvre.

Le point matériel

On va commencer par la physique du point matériel.

Un point matériel, c'est abstrait. C'est un truc qui n'a pas de forme, donc pas de volume, pas de sens, pas de... Bref, ça a une masse et c'est à peu près tout.

Bon.

Je dis déjà du bren.

Un point matériel n'a pas d'orientation, pas de volume ni de surface. C'est un point mathématique, mais auquel on a attaché des propriétés physiques. Genre une masse. On va commencer avec une masse. Pourquoi la masse ? Oh, ben à cause de la seconde loi de Newton :

La seconde loi de Newton, qu'on appelle simplement le principe fondamental de la dynamique. Alors du coup, hein, on va peut-être commencer par le fondamental ? On feera l'accessoire quand on sera fatigués ?

Le second principe de la dynamique

Que dit-il ?

D'abord, il dit que c'est un principe, donc qu'on ne va pas le démontrer. Ensuite il dit que c'est de la dynamique, donc c'est pour que les trucs et les machins ils bougent.

Ca fait con, dit comme ça, mais c'est super important. On traite de la dynamique, donc du mouvement, donc de l'espace. Ce qui va nous orienter vers un truc comme ça :

class PointMassif : public std::enable_shared_from_this
{
public:
    PointMassif();
    float masse() const;
    void setMasse(float newMasse);

    QVector3D pos() const;
    void setPos(const QVector3D &newPos);

    QString nom() const;
    void setNom(const QString &newNom);

private:
    QString _nom;
    QVector3D _pos;
};

Un point, c'est une masse à une position. Bon, on se doute bien qu'on va faire de la dynamique, donc on va... Je ne sais pas si vous vous souvenez en physique au lycée, quand on mettait des points au-dessus des lettres pour parler deleur dérivée par rapport au temps ?

Des dérivées

"Cosinus et sinus sont sur un bateau.
- Sinus tombe à l'eau ?
- Hein ? Ben non, pourquoi ?
- J'en sais rien, c'est ta blague, pas la mienne. Cosinus tombe à l'eau ?
- Ben non, t'est bizarre, toi, pourquoi tu fous tout le monde à la flotte ?
- Il se passe quoi alors ?
- Ils dérivent..."

Pour vous la faire courte et pas wikipédien, la dérivée de la position par rapport au temps, c'est la vitesse. C'est l'évolution de la position dans le temps. J'ai bougé de 30 km en une heure, j'avais donc une vitesse de 30 km/h. On dérive la vitesse de la position dans le temps.

C'est cette opération qu'on appelle la dérivée, et nous n'entrerons pas ici dans les démonstrations et calculs compliqués pour savoir les dérivées des fonctions usuelles, chose qu'on mange bien assez après le bac. De toute façon c'est inutile pour l'instant : on n'a pas de fonction à dériver. On va faire de la dérivation numérique. Et ça c'est facile : c'est la différence entre une valeur à une date, et cette même valeur à une date précédente, divisée par le temps écoulé entre les deux.

dx dt = x2 - x1 t2 - t1

Et on peut faire ça pour toutes les variables, y compris la vitesse. Et l'évolution de la vitesse par rapport au temps, on appelle ça l'accélération. Oui, les astronautes, tout ça. Leurs 10 g d'accélération, c'est de la dérivée de la vitesse par rapport au temps.

Alors ça marche avec la position, la vitesse, n'importe quoi en fait, hein. Je crois que la dérivée d'un volume, c'est le débit, tout ça...

Pour nous, on va rester à la définition la plus simpliste : la vitesse, c'est la différence entre deux positions (des km), divisée par le temps qu'on a mis (des h), ce qui nous donne des kilomètres par heure (des km/h).

Pareil pour le débit, qui est la différence de volume divisée par le temps écoulé (coucou la clepsydre). Pareil pour toutes les dérivées par rapport au temps.

Des intégrales

Ne blêmissez pas, au fond, tout va bien se passer. On s'essaie à la physique, pas aux maths de propédeutique.

Comment passe-t-on de la vitesse à la position ? Chrétien ? Non ? Lancelot ? Non plus ? Gauvain, ton cheval va à 16 km/h, où seras-tu dans 1/4 d'heure ? Chez les flics ? Non, Gauvain, non.

On va faire exactement l'inverse pour calculer la position à partir de la vitesse : ma nouvelle position, c'est mon ancienne position (j'étais forcément quelque part avant) plus ma vitesse multipliée par le temps passé à cette vitesse.

Le volume de ma bouteille, c'est le débit du liquide en se vidant, multiplié par le temps qu'il m'a fallu pour la vider. Si elle était vide, on part de zéro, mais on voit bien l'idée.

Ca me donne une idée

Comme on ne sait pas trop quelles sont les dérivées/intégrales dont on va avoir besoin, on va les définir comme ça :

template 
class Grandeur
{
public:
	Grandeur(const QString &nom):_nom(nom) {};
	void setValeur(T valeur, int ordre) {_mOrdreValeur[ordre] = valeur;};
	T getValeur(int ordre) const{
		if (!_mOrdreValeur.contains(ordre)) {
			_mOrdreValeur[ordre] = T();//Si on n'a pas cette valeur, on la construit par défaut.
		}
		return _mOrdreValeur[ordre];
	};
	void integre(int dt, int ordre = 0){
		auto ordres = _mOrdreValeur.keys();
		auto minMax = std::minmax_element(ordres.begin(), ordres.end());
		for (auto i = *(minMax.second); i > qMax(ordre, *(minMax.first)); --i)
		{
			setValeur(getValeur(i) * dt + getValeur(i-1), i-1);
		}
	};
private:
	QMap _mOrdreValeur;
	QString _nom;
};

Oh, une classe template ! Dès le premier chapitre ! Petit rappel, parce que je me fais avoir à chaque fois : il n'y a pas de .cpp pour les classes template. Que du .h, parce que c'est comme ça.

Bon, j'ai mis un champ "nom" qui ne va pas servir à grand-chose, histoire de voir ce qu'on affiche au cas où. La magie est dans la fonction integre : on part de l'ordre le plus élevé, et on les passe tous, qu'ils existent ou non, et on ajoute à l'ordre du dessus l'ordre courant, multiplié par le temps. Et une petite blague dans getValeur, où la valeur est construite si elle n'existe pas.

Donc on a fait la dynamique, mais le fondamental ?

L'idée est qu'à chaque instant, un point réagit à l'ensemble des forces qui lui sont appliquées. Ca ne parait pas débile : si on me tire à gauche et à droite, ben en fait je ne bouge pas. C'est le jeu du tir à la corde. Donc un point va accélérer selon la somme des forces qui lui sont appliquées. Et plus le point est lourd, plus il faut de force pour le mouvoir. Donc on va diviser la somme des forces par la masse du point, et puis c'est marre. Et ça tombe bien, parce que l'équation aux dimensions nous donne raison.