Il mio piccolo progetto di cui parlavo ieri sta
procedendo. Tralasciando i dettagli (che sono molti e molto noiosi), oggi lo
scopo è quello di rappresentare graficamente su un windows form la rotta che il
velivolo deve seguire.
Partendo da questo piano di
volo, vediamo essenzialmente che:
1) l'aereo parte dall'aeroporto di Alghero raggiungendo 10000 piedi di
quota
2) il primo waypoint è indicato dalla sigla [ALG], si trova a 2 miglia
dall'aeroporto. Bisogna raggiungere questo waypoint con un angolazione di 284°;
il nord è a 0°, l'est è a 90°, il sud a 180° e così via.
3) il secondo
waypoint è [AJO], distante 73 miglia da [ALG]
e così via (semplificando) fino
all'aeroporto di arrivo.
Notiamo come io in realtà non ho mai le coordinate esatte del punto che devo
raggiungere: ho solamente distanza e rotta rispetto al waypoint precedente. In
VB.NET ho disegnato una classe che incorpora tutti i dati relativi ad ogni
waypoint (heading, altitude, wind, description, etc.). Ho scritto una sub di cui
riporto il codice essenziale.
Private Sub Disegna()
gr = Me.picMap.CreateGraphics
gr.Clear(Color.LightGray)
'Prendo il primo flypoint (che è il decollo e lo metto al centro)
fly = NavigationLog.CheckPoint(0)
gr.TranslateTransform(Me.ClientSize.Width / 2 - Me.srcOriz.Value, Me.ClientSize.Height / 2 - Me.srcVert.Value)
DisegnaPunto(fly, COLOR_DEPARTURE, False)
...
'Prendo gli altri waypoint, escluso l'arrive
For i = 1 To NavigationLog.CheckPoint.Count - 2
fly = NavigationLog.CheckPoint(i)
DisegnaPunto(fly, COLOR_WAYPOINT, True)
Next
...
'Disegno l'arrive
fly = NavigationLog.CheckPoint(NavigationLog.CheckPoint.Count - 1)
DisegnaPunto(fly, COLOR_ARRIVE, False)
...
...
fly = Nothing
gr = Nothing
End Sub
gr è un oggetto Graphics che viene fatto puntare ad una PictureBox che
ho messo sul form. Cancello il contenuto riempiendolo con un colore uniforme
(Color.LightGray). NavigationLog è un oggetto che ingloba, tra le altre cose,
anche un ArrayList di CheckPoint. Dentro fly finisce il primo waypoint, ovvero
l'aeroporto del decollo.
Uso il metodo TranslateTransform di Graphics per
puntare le coordinate (0, 0) al centro della PictureBox. In questo punto
disegnerò l'aeroporto di partenza, che all'inizio quindi sarà sempre al centro
dello schermo. Concettualmente, il discorso è tutto qua: per ogni punto da
disegnare viene usata la sub DisegnaPunto.
Private Sub DisegnaPunto(ByVal Fly As FlyPoint, ByVal Colore As Color, ByVal Translate As Boolean)
Dim ang As Double
Dim x, y As Single
If Fly.Heading.CompareTo(Double.NaN) <> 0 Then
ang = Fly.Heading - 90
'Se l'angolo diventa negativo, calcolo il reciproco
If ang < 0 Then ang = 360 - Math.Abs(ang)
ang = (Math.PI * ang) / 180
y = Math.Sin(ang) * Me.barScala.Value
x = Math.Cos(ang) * Me.barScala.Value
End If
gr.DrawEllipse(New Pen(Colore), x, y, RADIUS, RADIUS)
If Translate Then gr.TranslateTransform(x, y)
End Sub
In breve, calcolo le coordinate x e y del punto. Come? Prendo
l'heading del waypoint: quando non esiste, Fly.Heading contiene Double.NaN per
cui salto la fase di calcolo. Se è valorizzato correttamente, vado avanti. Tolgo
90°: se ang < 0, allora il reciproco corretto è 360 - Abs(ang). Math.Sin e
Math.Cos vogliono l'angolo in radianti e quindi ang = (Math.PI * ang) / 180. A
questo punto disegno un ellisse con gr.DrawEllipse(New Pen(Colore), x, y,
RADIUS, RADIUS). A questo punto, cosa importantissima, traslo tutto, facendo in
modo che il punto appena disegnato abbia coordinate (0, 0).
Il codice in realtà è un po' più complesso: sul form ho messo due scrollbar
(horizontal e vertical) per fare il pan, e altri controlli per ruotare e per
regolare la scala. Inoltre, in DisegnaPunto ho usato i metodi DrawString e
DrawLine di gr per disegnare le linee tra un punto e l'altro e per scrivere una
label vicino a ciascun waypoint.
Torre, qui .NET applicato all'aeronautica, passo!