Elektronen – VB.Net Beispiel

Dieses Programm simuliert, wie sich Elektronen in einem Leiter verhalten. Man kann gut sehen, wie sich die Elektronen bei kleinem Strom nur langsam fortbewegen. Bei größeren Strömen werden die Elektronen aktiver und bewegen sich schneller durch den Leiter. Wenn kein Strom anliegt bewegen sich die Elektronen trotzdem ein wenig, aber ohne eine bestimmte Richtung zu bevorzugen. Dies nennt man Rauschen. Zu beachten ist, dass sich die Elektronen nie berühren, sondern immer leicht voneinander abstoßen.

Quelltextauszug I: Die Klasse Elektronen

Der Quelltext enthält eine große Neuerung. Es wird zum ersten Mal eine neue Klasse benutzt, die Klasse der Elektronen von der gleich mehrere Elemente erstellt werden:

Class Elektron
    ‚Klasse der Elektronen
    Dim canvas As New Microsoft.VisualBasic.PowerPacks.ShapeContainer
    Public Teil As New PowerPacks.OvalShape
    Dim PicBox As PictureBox
 
    Public Sub Zeichnen(ByVal x As Integer, ByVal y As Integer, ByVal Pb As PictureBox)
       ‚Erstellen des visuellen Teils eines Elektrons mit Parent: eine Pic-Box
        canvas.Parent = Pb
        Teil.Parent = canvas
        PicBox = Pb
        ‚Zufallsfunktion wenn beide Positionen nicht angegeben wurden
        If x = 0 And y = 0 Then
            Teil.Left = xRnd()
            Teil.Top = YRnd()
        Else
            Teil.Left = x
            Teil.Top = y
        End If
 
        ‚Visuelle Eigenschaften der Elektronen
        Teil.Width = 17
        Teil.Height = 17
        Teil.FillColor = Color.DarkBlue
        Teil.FillStyle = PowerPacks.FillStyle.Solid
        Teil.FillGradientStyle = PowerPacks.FillGradientStyle.Central
    End Sub
 
    Public Sub Move(ByVal fx, ByVal fy, ByVal vspeed)
        ‚Wenn über den Bildrand hinaus, von vorne anfangen
        If Teil.Left > PicBox.Width – 20 Then
            Teil.Left = 0
        End If
        ‚Berechnung der neuen Position mit einbeziehung von Geschwindigkeit und Kräften
        Me.Teil.Left = Me.Teil.Left + fx + vspeed + 6 * Rnd() – 3
        Me.Teil.Top = Me.Teil.Top + fy + 6 * Rnd() – 3
    End Sub
 
    Private Function xRnd()
        ‚Zufallsfunktion für X-Werte
        Return Rnd() * (PicBox.Width – 34)
    End Function
    Private Function YRnd()
        ‚Zufallsfunktion für Y-Werte
        Return Rnd() * (PicBox.Height – 20)
    End Function
 
End Class

Dies ist die Klasse. Sie enthält öffentliche Prozeduren wie Zeichnen und Move und interne Funktionen (xRnd, YRnd) die nicht von einer anderen Klasse aus aufgerufen werden können.  Wenn die Prozedur zeichnen aufgerufen wird, werden die visuellen Teile des Elektrons erstellt. Wenn als Parameter noch X und Y Koordinaten angegeben wurden, wird das Elektron dort positioniert. Wenn beide Parameter Null sind, wird das Elektron zufällig auf der Picturebox platziert. Die Prozedur Move ist dafür da, das Elektron in Abhängigkeit von angegebenen x/y-Kräften und einer Geschwindigkeit, in eine gewünschte Richtung zu bewegen.

            Dim neuElektron As New Elektron
            Elektronen(20 + i + 1) = neuElektron

Diese beiden oberen Zeilen zeigen, wie ein Elektron zuerst konstruiert wird und anschließend einem Index bekommt, indem es einer Array des Typs Elektron zugewiesen wird.

Quelltextauszug II: Verhalten der Elektronen

Sie werden sich sicher wundern, warum die Elektronen sich nicht über die Wand hinaus bewegen. Grund dafür ist, dass in der Wand ebenfalls nicht sichtbare Elektronen positioniert sind (Eine Potentialgrenze genau genau wie in der Realitätm, real allerdings durch das Fehlen der Atomrümpfe am Rand). Man kann dies ganz gut in diesem Programmteil sehen:

        ‚Die virtuellen Wandelektronen werden konstruiert, zufällig positioniert und angezeigt
        For i = 0 To anzWand / 2
            Dim neuElektron As New Elektron
            vx = (pb1.Width / 10) – 5
            vy = -18
            If i = 0 Then
                neuElektron.Zeichnen(1, vy, pb1)
            Else
                neuElektron.Zeichnen(vx * i, vy, pb1)
            End If
            Elektronen(20 + i + 1) = neuElektron
        Next
        ‚unten das Gleiche
        For i = 0 To anzWand / 2
            Dim neuElektron As New Elektron
            If i > 10 Then vy = 115 Else vy = 0
            vx = (pb1.Width / 10) – 5
            vy = 133
            neuElektron.Zeichnen(vx * i, vy, pb1)
            Elektronen(30 + i + 2) = neuElektron
        Next

Der Grund warum sich die Elektronen nicht gegenseitig berühren liegt in diesem Teil des Quelltextes. Für jedes Elektron wird die  abstoßende Kraft aller anderen  Elektronen berechnet. Wenn mal eins zu nahe kommt, wird die Anstoßung überproportional groß:

    Private Sub Kraefte(ByVal i As Integer)
        Dim dx, dy, s2, kf
        Dim fx = 0
        Dim fy = 0
        ‚gegenüber sämtliche Elektronen werden die Kräfte berechnet
        For n = 1 To anzElem
            If i <> n Then
                dx = Elektronen(n).Teil.Left – Elektronen(i).Teil.Left
                dy = Elektronen(n).Teil.Top – Elektronen(i).Teil.Top
                ‚Formel fürs Kräfte berechnen
                s2 = dx ^ 2 + dy ^ 2
                kf = 900 / s2 / Math.Sqrt(s2)
                fx = fx – dx * kf
                fy = fy – dy * kf
            End If
        Next n

Diese Prozedur wird immer wieder aufgerufen und berechnet die Kräfte zwischen sämtlichen Elektronen nach dieser Formel:

                s2 = dx ^ 2 + dy ^ 2
                kf = 900 / s2 / Math.Sqrt(s2)
                fx = fx – dx * kf
                fy = fy – dy * kf

Dx und dy sind die Abstände der beiden Elektronen auf der x und auf der Y-Achse. Daraus wird die Kraft kf berechnet. Diese Kraft wird dann in den letzten beiden Zeilen in Kräfte in X und in Y-Richtung umgerechnet. Diese kann man dann an die Move-Prozedur weitergeben.

Damit die Berechnung aller Elektronen nicht zu lange dauert und dadurch eine sehr ruckelige Darstellung entsteht, werden in dem Timeraufruf immer nur vier Elektronen auf einmal berechnet. Auf langsameren Rechnern könnte die Berechnung dennoch zu einer hackenden Darstellung führen.

Quelltextauszug III: Parameter

Sie können auch mit einfachen Mitteln das Programm um ein paar Elektronen erweitern. In den ersten Zeilen des Programms stehen dazu die passenden Parameter (anzElek: Elektronen Anzahl, anzWand = Wandelektronen Anzahl). Auch die Grundgeschwindigkeit der Elektronen (vspeed) lässt sich hier variieren.

    Dim anzElek = 20        ‚Elektronen
    Dim anzWand = 24        ‚virtuelle Wand-Elektronen
    Dim anzElem = anzElek + anzWand ‚gesammte Anzahl
    Dim vspeed = 2      ‚Startgeschwindigkeit der Elektronen

Der gesamte Quelltext

Public Class frmElektronen
Dim anzElek = 20        ‚Elektronen
Dim anzWand = 24        ‚virtuelle Wand-Elektronen
Dim anzElem = anzElek + anzWand ‚gesammte Anzahl
Dim vspeed = 2      ‚Startgeschwindigkeit der Elektronen
Dim vi              ‚Index für Elektronenberechnungen im Timer
Dim Elektronen(anzElek + anzWand) As Elektron

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
‚Vier Elektronen werden in einem Timeraufruf berechnet
For i = 1 To 4
vi = vi + 1
Kraefte(vi)
If vi = anzElek Then vi = 0
Next
End Sub

Private Sub frmElektronen_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesMyBase.Load
Dim el1 As New Elektron
Dim vx, vy
‚Beim Programmstart werden die Elektronen konstruiert, zufällig positioniert und angezeigt
For i = 1 To anzElek
Dim neuElektron As New Elektron
neuElektron.Zeichnen(0, 0, pb1)
Elektronen(i) = neuElektron
Next
‚Die virtuellen Wandelektronen werden konstruiert, zufällig positioniert und angezeigt
For i = 0 To anzWand / 2
Dim neuElektron As New Elektron
vx = (pb1.Width / 10) – 5
vy = -18
If i = 0 Then
neuElektron.Zeichnen(1, vy, pb1)
Else
neuElektron.Zeichnen(vx * i, vy, pb1)
End If
Elektronen(20 + i + 1) = neuElektron
Next
‚unten das Gleiche
For i = 0 To anzWand / 2
Dim neuElektron As New Elektron
If i > 10 Then vy = 115 Else vy = 0
vx = (pb1.Width / 10) – 5
vy = 133
neuElektron.Zeichnen(vx * i, vy, pb1)
Elektronen(30 + i + 2) = neuElektron
Next
End Sub

Private Sub Kraefte(ByVal i As Integer)
Dim dx, dy, s2, kf
Dim fx = 0
Dim fy = 0
‚gegenüber sämtliche Elektronen werden die Kräfte berechnet
For n = 1 To anzElem
If i <> n Then
dx = Elektronen(n).Teil.Left – Elektronen(i).Teil.Left
dy = Elektronen(n).Teil.Top – Elektronen(i).Teil.Top
‚Formel fürs Kräfte berechnen
s2 = dx ^ 2 + dy ^ 2
kf = 900 / s2 / Math.Sqrt(s2)
fx = fx – dx * kf
fy = fy – dy * kf
End If
Next n
‚Prozedure lässt das Elektron entsprechend den Kräften bewegen
Elektronen(i).Move(fx, fy, vspeed)
End Sub

Private Sub HScrollBar1_Scroll(ByVal sender As System.Object, ByVal e AsSystem.Windows.Forms.ScrollEventArgs) Handles HScrollBar1.Scroll
‚Geschwindigkeit variieren
vspeed = HScrollBar1.Value
End Sub

Private Sub pb1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles pb1.Click
End Sub
End Class

Class Elektron
‚Klasse der Elektronen
Dim canvas As New Microsoft.VisualBasic.PowerPacks.ShapeContainer
Public Teil As New PowerPacks.OvalShape
Dim PicBox As PictureBox

Public Sub Zeichnen(ByVal x As Integer, ByVal y As Integer, ByVal Pb As PictureBox)
‚Erstellen des visuellen Teils eines Elektrons mit Parent: eine Pic-Box
canvas.Parent = Pb
Teil.Parent = canvas
PicBox = Pb
‚Zufallsfunktion wenn beide Positionen nicht angegeben wurden
If x = 0 And y = 0 Then
Teil.Left = xRnd()
Teil.Top = YRnd()
Else
Teil.Left = x
Teil.Top = y
End If

‚Visuelle Eigenschaften der Elektronen
Teil.Width = 17
Teil.Height = 17
Teil.FillColor = Color.DarkBlue
Teil.FillStyle = PowerPacks.FillStyle.Solid
Teil.FillGradientStyle = PowerPacks.FillGradientStyle.Central
End Sub

Public Sub Move(ByVal fx, ByVal fy, ByVal vspeed)
‚Wenn über den Bildrand hinaus, von vorne anfangen
If Teil.Left > PicBox.Width – 20 Then
Teil.Left = 0
End If
‚Berechnung der neuen Position mit einbeziehung von Geschwindigkeit und Kräften
Me.Teil.Left = Me.Teil.Left + fx + vspeed + 6 * Rnd() – 3
Me.Teil.Top = Me.Teil.Top + fy + 6 * Rnd() – 3
End Sub

Private Function xRnd()
‚Zufallsfunktion für X-Werte
Return Rnd() * (PicBox.Width – 34)
End Function
Private Function YRnd()
‚Zufallsfunktion für Y-Werte
Return Rnd() * (PicBox.Height – 20)
End Function
End Class

[collapse]

Download Projektdatei

Wenn Sie nur an der Exe-Datei interessiert sind, befindet sich diese in dem Unterordner \bin\Debug.