WindDriftMaster


Présentation


Bonjour à tous. Je vous propose gratuitement WindDriftMaster (et pour les moteurs de recherche, Wind Drift Master), une version interactive diffusée sur le Microsoft Store ici et en version web ici.

WindDriftMaster est un simulateur et jeu de navigation aérienne permettant de calculer route, cap, dérive, vitesse sol et temps de vol en présence de vent. Le tracé en temps réel des triangles des vitesses dans la fenêtre graphique rend les concepts très faciles à comprendre et le mode jeu permet de s’exercer de manière ludique pour apprendre en s’amusant (texte de présentation plus détaillé ici).

J’envisage prochainement une diffusion sur Android et Apple.


Vidéos


Voici une présentation générale après publication sur le Microsoft Store.

Voici une vidéo de présentation de l’interface en version 1.3, permettant de comprendre le fonctionnement du logiciel.

Présentation de l’interface 1.3

Et son évolution 1.5 avec des boutons repensés.

Evolution vers l’interface 1.5.3 – Boutons améliorés

Dans la prochaine vidéo, voyez comment trouver rapidement, précisément et sans calculs cap, dérive, vitesse sol et temps avec vent sur un tronçon de navigation.

Préparer sa navigation

Dans la prochaine vidéo, voyez comment utiliser un « Flight Computer » (LIEN E6-B) en faisant un lien très visuel avec le triangle des vitesses sur WindDriftMaster.

Et Chloé, 10 ans, vous présente sa version de l’utilisation d’un « Flight Computer » :

Dans la prochaine vidéo, voyez comment calculer de manière exacte la dérive et la vitesse sol en présence de vent en triangle rectangle en utilisant la trigonométrie (sin, cos) et Pythagore.

Dans la prochaine vidéo, voyez comment calculer de manière approchée la dérive et la vitesse sol en présence de vent en utilisant le facteur de base.

Dans la prochaine vidéo, voyez comment calculer rapidement le cap et la vitesse sol connaissant le vent et une cible géométriquement en construisant graphiquement le triangle des vitesses.

Dans la prochaine vidéo, voyez comment calculer très précisément cap et temps pour atteindre la cible en présence de vent en utilisant la trigonométrie, le théorème d’Al-Kashi et une équation du second degré dans tous les triangles.


Calculs et sujet


Retrouvez les éléments mathématiques à l’origine de ce jeu ici.

Enseignant en Lycée ? Je vous propose une application pédagogique sur le vol mettant en œuvre la trigonométrie (cos, sin, tan) et leurs inverses, Pythagore, Al-Kachi, résolution d’équations du second degré, vecteurs et constructions géométriques. Trouvez ci-dessous un sujet :

  • Sujet : PDF – WORD
  • Correction : A me demander par mail (lien en bas de page) depuis votre mail académique

Téléchargement


Version de WindDriftMaster en cours: 1.5.5

Lien Microsoft Store


Détails de la création


J’ai d’abord développé ce jeu sous le nom « Jeu Dérive » en langage Python simple, dont le code peut être copié ci-dessous et collé dans votre logiciel Python préféré pour y jouer simplement.

Faire apparaître le code
## Auteur et version

print("Auteur: Denis DEFAUCHY")
print("Version: 1.2.2")
print("")

## Librairies

print("Chargement")
print("")
from math import sqrt,acos,cos,sin,pi
from random import randint as rd
from matplotlib import pyplot as plt
plt.close('all')
from time import sleep as dodo
from time import perf_counter as tps

## Fonctions d'affichage

def Aff_Fig(fig):
    plt.figure(fig,figsize=(8,8))

def Aff_Fleche(fig,V,D,col):
    plt.figure(fig)
    x,y = 0,0
    dx = V*sin(D*pi/180)
    dy = V*cos(D*pi/180)
    plt.arrow(x,y,dx,dy,width=1,head_width=5,head_length=5,length_includes_head=True,color=col)

def Aff_Point(fig,P):
    plt.figure(fig)
    plt.plot(P[0],P[1],'o-k',markersize=5)

def Aff_Cible(fig,P,R):
    plt.figure(fig)
    L_teta = [i*2*pi/360 for i in range(360)]
    LX = [P[0]+R*cos(t) for t in L_teta]
    LY = [P[1]+R*sin(t) for t in L_teta]
    plt.plot(LX,LY,'b')

def Aff_Droite(fig,Lx,Ly,col,Type):
    plt.figure(fig)
    plt.plot(Lx,Ly,col+"-"+Type,linewidth=2)

def Affiche(fig):
    plt.figure(fig)
    plt.axis('scaled')
    plt.xlim([-150,150])
    plt.ylim([-150,150])
    plt.show()
    plt.pause(1)
    # Nécessaire sous Python - A enlever sur trinket.io (non compatible) - Permet d'afficher la figure au moment de input, sinon figure vide
    dodo(2)
    # Inutile sous Python - Nécessaire sour trinket.io - Permet d'éviter un bug sur où la figure apparaît, cap est demandé avant et le cap à entrer est après

## Type de jeu

print("Type:")
print("- 1: Triangle rectangle")
print("- 2: Triangle quelconque")
print("")

Type = ""
while Type !='1' and Type!='2':
    Type = input('Type ? ')
Type = int(Type)
print("")

## Mode de jeu

print("Modes:")
print("- 0: Démo")
print("- 1: Facile")
print("- 2: Moyen")
print("- 3: Difficile")
print("- 4: Nightmare")
print("")

Mode = ""
while Mode != '0' and Mode !='1' and Mode!='2' and Mode != '3' and Mode != '4':
    Mode = input('Mode ? ')
Mode = int(Mode)
print("")

if Mode == 1:
    Cible_R = 30
elif Mode == 2:
    Cible_R = 20
elif Mode == 3:
    Cible_R = 10
else: # Modes 0 et 4
    Cible_R = 2

## Mise en place du problème

print("Données:")

# Cible
print("- Rayon de la cible:",Cible_R,"nm")
Cible_Dst = rd(80,120)
Cible_Dir = rd(0,359)
Cible_X = Cible_Dst*sin(Cible_Dir*pi/180)
Cible_Y = Cible_Dst*cos(Cible_Dir*pi/180)
Cible = [Cible_X,Cible_Y]
print("- Cible:",Cible_Dir,"° /",Cible_Dst,"nm")

# Vent: Vv < Va nécessaire
Vv_min = 10
Vv_max = 30
Vv = rd(Vv_min,Vv_max)
if Type==1:
    Signe = 1
    if rd(0,1)==1:
        Signe = -1
    Pv = (Cible_Dir + Signe*90)%360
else:
    Pv = rd(0,359)
Dv = (Pv+180)%360
print("- Vent:",Pv,"°/",Vv,"kt")

# Avion
Va_min = 50
Va_max = 100
Va = rd(Va_min,Va_max)
print("- Avion:",Va,"kt")

print("")

## Affichage

Aff_Fig(1)
Aff_Cible(1,Cible,Cible_R)
Aff_Fleche(1,Va,Cible_Dir,"r")
Aff_Fleche(1,Vv,Dv,"b")
Affiche(1)

## Consignes

if Mode != 0:
    print("Consignes:")
    print("- Flèche bleue: Vent")
    print("- Flèche rouge: Vitesse avion sans vent orientée vers la cible")
    print("- Rond bleu: cible à atteindre")
    print("")
    print("Sans vent en 60 minutes, vous arriverez au bout de la flèche rouge")
    print("")
    print("Choisir cap et temps pour atteindre la cible")
else:
    print("Visualisation de la trajectoire sous l'effet du vent en 60 minutes de vols pour un cap vers la cible")
print("")

## Paramètres

tic = tps()
if Mode != 0:
    Cap = float(input("Cap (°): "))
    Temps = float(input("Temps (minutes): "))
    print("")
else:
    Cap = Cible_Dir # On va dériver
    Temps = 60
toc = tps()

## Résolution

# Vs
Alpha = (Dv-Cap)%360
Vs = round(sqrt(Vv**2+Va**2+2*Vv*Va*cos(Alpha*pi/180)),2) # Solution positive
Dst = round(Vs*Temps/60,2)

# D
Derive_Rd = acos((Va**2+Vs**2-Vv**2)/(2*Va*Vs))
Derive_Deg = round((Derive_Rd*180/pi)%360,2)
if  Alpha <= 180:
    Signe = 1
else:
    Signe = -1
Derive = Signe*Derive_Deg
Route = round((Cap+Derive)%360,2)

print("Résultats: ")
print("- Distance parcourue:",Dst,"nm")
print("- Dérive:",Derive,"°")
print("- Vitesse sol:",Vs,"kt")
print("- Route:", Route,"°")
print("")

## Affichage de la solution

N = 10
LD = [i*Cible_Dst/N for i in range(N+1)]
LX_Traj = [d*sin(Route*pi/180) for d in LD]
LY_Traj = [d*cos(Route*pi/180) for d in LD]

LD = [i*Dst/N for i in range(N+1)]
LX_Route = [d*sin(Route*pi/180) for d in LD]
LY_Route = [d*cos(Route*pi/180) for d in LD]
Arr_X,Arr_Y = LX_Route[-1],LY_Route[-1]
Arrivee = [Arr_X,Arr_Y]

Aff_Fig(2)
Aff_Cible(2,Cible,Cible_R)
Aff_Fleche(2,Va,Cap,"r")
Aff_Fleche(2,Vv,Dv,"b")
if Mode != 0:
    Aff_Droite(2,LX_Traj,LY_Traj,'y','-')
Aff_Droite(2,LX_Route,LY_Route,'k','')
Aff_Point(2,Arrivee)
Affiche(2)

## Affichage du temps de résolution

Temps = int(round(toc - tic,0))
if Mode != 0:
    print('Temps mis pour résoudre le problème: ' + str(Temps) + ' s')

## Vérification de la réussite

if Mode != 0:
    # Cap - Distance de la cible à la droite (route suivie par l'avion)
    X1,Y1 = 0,0
    X2,Y2 = Arrivee
    if X1==X2: # x = ...
        A = 1
        B = 0
        C = -X1
    else: # y = ax+b
        a = (Y2-Y1)/(X2-X1)
        b = Y1-a*X1
        A = a
        B = -1
        C = b
    X,Y = Cible
    num = A*X+B*Y+C
    denom = sqrt(A**2+B**2)
    d = abs(num/denom)
    if d > Cible_R:
        print("Cap faux")
    else:
        # Limiter au bon demi plan
        Delta_Route = abs(Route-Cible_Dir)
        if Delta_Route > 180:
            Delta_Route = 360 - Delta_Route
        if Delta_Route <= 90: # L'origine ne doit pas être dans la cible (évidemment)
            print("Bravo: Cap OK")
        else:
            print("Cap faux")
    # Vitesse - Dans le cercle ?
    Ecart_X = Cible[0] - Arr_X
    Ecart_Y = Cible[1] - Arr_Y
    Ecart_Centre = round(sqrt(Ecart_X**2+Ecart_Y**2),2)
    Manque = Ecart_Centre - Cible_R
    Manque = (Manque + abs(Manque)) / 2 # Partie positive
    Manque = round(Manque,2)
    print("Distance au centre de la cible:",Ecart_Centre,"nm")
    print("Distance à la cible:",Manque,"nm")
    if Ecart_Centre <= Cible_R:
        print("Bravo: Cible atteinte")
    else:
        print('Oups: Cible manquée')
    print("")

## Calcul de la solution attendue

Alpha_prime = (Dv-Cible_Dir)%360
Vs_sol = Vv*(cos(Alpha_prime*pi/180)+sqrt(cos(Alpha_prime*pi/180)**2+(Va/Vv)**2-1))
D_sol = acos((Va**2+Vs_sol**2-Vv**2)/(2*Va*Vs_sol))*180/pi
if  Alpha_prime <= 180:
    Signe = 1
else:
    Signe = -1
D_sol = Signe*D_sol
C_sol = (Cible_Dir-D_sol)%360
T_sol = 60*Cible_Dst/Vs_sol

C_sol = round(C_sol,2)
T_sol = round(T_sol,2)
D_sol = round(D_sol,2)
Vs_sol = round(Vs_sol,2)

print("Solution du problème:")
print("Cap attendu: ",C_sol,"°")
print("Temps attendu: ",T_sol,"minutes")
print("Dérive: ",D_sol,"°")
print("Vitesse sol: ",Vs_sol,"kt")
print("")

## Fin

print("Fin du jeu !")

Découvrant le module kivy sous Python, j’ai ensuite voulu aller plus loin ! J’ai donc réalisé WindDriftMaster.

Pour cela, j’ai utilisé la version 3.13.2 de Python, sous Pyzo 4.19.0 en utilisant le module kivy 2.3.1 installé via pip (python). Je l’ai compilé en « .exe » depuis l’invite de commande cmd de Windows avec pyinstaller 6.12.0 installé lui aussi avec pip. J’ai créé l’installateur setup avec innosetup 6.6.0 que j’ai alors proposé sur le Microsoft Store.

Par ailleurs, j’ai utilisé l’IA d’OpenAI avec Codex pour en proposer la version web rendant WindDriftMaster accessible multiplateforme via un navigateur.


Mises à jour


VersionDateChangements
1.111/03/2025Première version diffusée
1.212/03/2025– Support langue anglaise
– Changement de nom
– Diverses améliorations
1.312/03/2025– Correction d’un bug sur << Relancer >>
– Ajout de liens sur les textes de la zone de jeu
– Diverses améliorations
1.414/03/2025– Adaptation automatique du max du slider
distance cible selon rayon cible
– Mini distance cible baissé à 20 nm
en mode démo, reste à 50 en jeu
– Triangle rectangle maintenant impossible
à obtenir en mode quelconque
– Score remis à 0 au changement de type de triangles
par utilisation des deux boutons de choix
Il est volontairement maintenu en mode démo
si le type de triangles change par les sliders
1.523/03/2025Amélioration des boutons de choix
Triangles et Mode
Nom de la fenêtre « Derive » devenu « WindDriftMaster »
1.5.123/03/2025Correction d’un possible maintien noir des boutons
Suppression du clic droit avec rond rouge
Suppression >< du texte >>Start<<
1.5.223/03/2025Correction d’un problème de couleur orange
sur les boutons des types de triangles
1.5.323/03/2025Aucun ressenti utilisateur
Modification de la gestion des changements de types
de triangles avec etat_jeu remis à 0 dans relancer
1.5.401/04/2025Suppression << >> autour de « Faire un don »
1.5.505/04/2025Notation: « nm » devient « NM »
1.5.518/11/2025Première version en ligne sur le Microsoft Store

Commentaires


Un bug ? Une suggestion ? Un remerciement ? Laissez moi des commentaires en bas de cette page 😉


Merci à la @ffaero ✈️ et @francois.lgd pour l’article sur WindDriftMaster 💨🧭 dans l’actu FFA de Mai 2025 📅


Merci à info-pilote pour la publicité à propos de WindDriftMaster sur leur site ici:

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Les Sciences Industrielles de l'Ingénieur (SII) et l'Informatique du Tronc Commun (ITC) en CPGE par Denis DEFAUCHY