Ereignisgesteuerte Animation

 

Event-driven Animation  -  Abstract

 

Algorithms can be visualized by means of event-driven animation. Within an event-driven animation, the class containing the algorithm is programmed as usual, the only difference being the definition of custom events at the critical points of the algorithm. For the animation, the algorithm will be run. During execution the events triggered by the algorithm will be received within an object of another class, the Animator class. The Animator object will then transform the events into the animation output to be seen by the user.

 

 

Mit Hilfe der ereignisgesteuerten Programmierung lassen sich in Excel-VBA gut Animationen erzeugen, welche den Ablauf von Algorithmen veranschaulichen.  Gegenüber dem Einsatz eines spezialisierten Animationswerkzeugs hat diese Lösung folgende Vorteile

 

  • Es muss kein zusätzliches Animationswerkzeug gekauft werden
  • Die ursprüngliche Programmierung des Algorithmus, der veranschaulicht werden soll, kann beibehalten werden. Sie muss lediglich um einige Anweisungen ergänzt werden, welche die für die Animation wichtigen Ereignisse auslösen.
  • Die Animationslösung kann eine Schichtenarchitektur besitzen, welche eine klare Trennung zwischen Programmkern und Benutzersteuerung (UI) einschließt.

 

 

 

Prinzip der ereignisgesteuerten Animation

 

Das Prinzip  ist einfach und lässt sich in einem Satz beschreiben:

 

Bei der Durchführung des Algorithmus werden an den entscheidenden Stellen Ereignisse ausgelöst, welche von einem anderen Modul aufgefangen und in eine bildliche Darstellung umgesetzt werden.

 

 

 

Erläuterung an einem Beispiel

 

Zur Illustration der Technik soll ein ganz einfaches Beispiel verwendet werden. Der zu animierende Algorithmus produziert die Collatzfolgen für eine Liste von Startzahlen. Die Animation soll daraus bestehen, dass die Ausgabe des Ergebnisses nicht en bloc auf einem Arbeitsblatt erfolgt, wie dies normalerweise geschähe, sondern dass die Ausgabe so verzögert erfolgt, dass der Betrachter die Folge Zahl für Zahl entstehen sieht.  Außerdem sollen gerade und ungerade Folgenglieder in unterschiedliche Farben ausgegeben werden, weil die Berechnung eines Folgenelements davon abhängt, ob der Vorgänger gerade ist oder nicht.

 

Für die Folgen mit den Startzahlen 2 bis 7 würde die Ausgabe nach Ende der Animation folgendermaßen aussehen:

 

2

1

                             

3

10

5

16

8

4

2

1

                 

4

2

1

                           

5

16

8

4

2

1

                     

6

3

10

5

16

8

4

2

1

               

7

22

11

34

17

52

26

13

40

20

10

5

16

8

4

2

1

 

Wie man sieht, wurden gerade Zahlen blau gedruckt, ungerade rot.

 

 

 

 

Der Aufbau des Animationsprogramms

 

Wir können für diese und ähnliche Animationen eine dreischichtige  Architektur verwenden.  Im folgenden Bild ist auf der linken Seite der Aufbau in allgemein formulierten Modulbenennungen abgebildet, rechts sind die in unserem Beispiel verwendeten Module zu sehen.  Bei den beiden unteren Schichten handelt es sich jeweils um Klassenmodule. Dies ist eine Voraussetzung für die Anwendung der ereignisgesteuerten Programmierung.

 

 

Mit Hilfe der obersten Schicht, dem UI, werden die Parameter der Animation gesetzt bzw. eingelesen. In unserem Beispiel gehören zu den Parametern die Liste der Startzahlen, das Arbeitsblatt, auf dem die Animation ausgegeben werden soll, und die Dauer der zeitlichen Verzögerung, die zwischen die einzelnen Durchführungsschritte geschoben werden soll.

 

Das UI gibt die Parameter mit einem Aufruf an die zweite Schicht weiter, ein Objekt der Animator-Klasse bzw., in unserem konkreten Fall, ein Objekt der Klasse CollatzAnimator.  Dieses Objekt führt die Animation durch, indem es ein Objekt der untersten Schicht mit der Durchführung des Algorithmus beauftragt, die in diesem Objekt ausgelösten Ereignisse auffängt und in die bildliche Darstellung auf dem Arbeitsblatt einfügt.

 

Welche Ereignisse für die Animation relevant sind, hängt von dem zu animierenden Algorithmus ab und muss vom Programmierer entschieden werden. Gewöhnlich wird man die Stellen im Algorithmus auswählen, an denen „die Weichen gestellt“ werden. In unserem Beispiel sind dies zwei Ereignisse:

 

  • der Beginn einer neuen Collatzfolge,
  • die Errechnung eines weiteren Elements in der Folge, die gerade entwickelt wird.

 

 

 

Das Programm

 

Wir beginnen mit der Betrachtung des Codes auf der untersten Stufe der Architektur. Dies ist die Klasse CollatzSequence. Sie besteht aus zwei Funktionen. Die Funktion CollatzArray2 liefert die Folgen für die in z gelisteten Startzahlen als geschachteltes Array vom Typ Variant.  In diesem Ergebnis-Array ist für jede Startzahl ein Array vom Typ Long enthalten, das von der Funktion CollatzFolge an Funktion CollatzArray2 geliefert wird.  

 

Der Code der Klasse ist gegenüber einer Normalfassung, welche nur der Berechnung der Folgen dient, nahezu unverändert. Lediglich die Definition der Ereignisse und die RaiseEvent-Anweisungen zur Auslösung dieser Ereignisse sind hinzugekommen (grün hervorgehoben).

 

Beachten Sie, dass die Ereignisse mit Parametern definiert sind. Diese Parameter enthalten die Informationen, welche innerhalb der Animator-Klasse zur Darstellung der Ereignisse auf dem Arbeitsblatt erforderlich sind.

 

‘----------------------------------

‘Class CollatzSequence

‘----------------------------------

 

Option Explicit

 

Public Event newStart(ByVal sNum As Long)

Public Event nextNum(ByVal nNum As Long)

 

 

'produces Collatz sequence starting with z

'-------------------------------------------------------------

Public Function CollatzFolge(ByVal z As Long) As Long()

    Dim c() As Long

    Dim n As Integer

    n = 1

    ReDim c(1 To n)

    c(n) = z

    Do While z > 1

        n = n + 1

        ReDim Preserve c(1 To n)

        z = IIf(z Mod 2 = 0, z \ 2, 3 * z + 1)

        RaiseEvent nextNum(z)

        c(n) = z

    Loop

    CollatzFolge = c

End Function

 

 

'provides a nested array containing Collatz sequences based on

'the starting numbers listed in z

'---------------------------------------------------------------------------------------------

Public Function CollatzArray2(ByRef z() As Long) As Variant

    Dim f() As Variant

    ReDim f(LBound(z) To UBound(z))

    Dim i As Integer, j As Integer

    For i = LBound(z) To UBound(z)

        RaiseEvent newStart(z(i))

        f(i) = CollatzFolge(z(i))

    Next i

    CollatzArray2 = f

End Function

 

 

Die mittlere Ebene besteht aus der Klasse CollatzAnimator.  Die Klasse besitzt eine Instanzenvariable cs vom Typ CollotzSequence, welche mit der Durchführung des Algorithmus betraut wird. Wichtig ist, dass diese Variable mit dem Zusatz WithEvents deklariert wird. Die weiteren Instanzenvariablen sind: currRow (aktuelle Ausgabezeile), currCol (aktuelle Ausgabespalte), w (das Ausgabe-Arbeitsblatt) und dly (die gewünschte zeitliche Verzögerung zwischen den Einzelschritten).

 

Die Hauptprozedur ist doAnimation. Dies ist die Prozedur, die aus dem UI zur Ausführung der Animation aufgerufen wird. Prozedur doAnimation bereitet das Arbeitsblatt für die Ausgabe vor und beauftragt das Objekt cs mit der Durchführung des Algorithmus. Beachten Sie, dass die Rückgabe der Funktion CollatzArray2 nicht verwertet wird; die Funktion wird wie eine Prozedur aufgerufen. Auf die Lieferung von CollatzArray2 kann verzichtet werden, weil alle Ausgaben bereits während der Algorithmusdurchführung innerhalb der beiden Ereignisprozeduren cs_newStart und cs_nextNum durchgeführt werden.

 

Prozedur cs_newStart tritt in Aktion, sobald im Algorithmus die Bearbeitung einer neuen Collatzfolge begonnen wird.  Die Prozedur macht rückt im Arbeitsblatt in die nächste Zeile vor und schreibt in deren erste Spalte die Startzahl der neu begonnenen Folge.

 

Die Prozedur cs_nextNum wird für jedes neu gefundene Element innerhalb einer Folge durchgeführt. Sie rückt innerhalb der aktuellen Ausgabezeile um eine Spalte nach rechts und schreibt dorthin das neue Element.

 

Beide Ereignisprozeduren rufen während ihrer Durchführung die Prozedur delay auf und veranlassen damit eine Verzögerung der Ausführung.

 

‘---------------------------------

‘Class CollatzAnimator

‘---------------------------------

 

Option Explicit

 

Private WithEvents cs As CollatzSequence

Private currRow As Long

Private currCol As Long

Private w As Worksheet

Private dly As Single

 

 

'controls the animation

'--------------------------------

Public Sub doAnimation(ByVal outW As Worksheet, _

                       ByRef sNums() As Long, _

                       ByVal delay As Single)

                      

    Set w = outW

    Set cs = New CollatzSequence

    dly = delay

    currRow = 0

    w.Cells.Clear

    w.Cells.Font.Color = vbBlack

    w.Cells.ColumnWidth = 5

   

    cs.CollatzArray2 sNums

   

End Sub

 

 

 

'event procedure: a new sequence has been started

'-------------------------------------------------------------------------

Private Sub cs_newStart(ByVal sNum As Long)

    currRow = currRow + 1

    currCol = 1

    If sNum Mod 2 = 0 Then

        w.Cells(currRow, currCol).Font.Color = vbBlue

    Else

        w.Cells(currRow, currCol).Font.Color = vbRed

    End If

   

    w.Cells(currRow, currCol) = sNum

    delay dly

End Sub

 

 

'event procedure: a new element has been added

'---------------------------------------------------------------------

Private Sub cs_nextNum(ByVal nNum As Long)

    currCol = currCol + 1

    If nNum Mod 2 = 0 Then

        w.Cells(currRow, currCol).Font.Color = vbBlue

    Else

        w.Cells(currRow, currCol).Font.Color = vbRed

    End If

    w.Cells(currRow, currCol) = nNum

    delay dly

End Sub

 

 

'causes a delay

'---------------------

Private Sub delay(ByVal duration As Single)

    Dim t As Single

    t = Timer

    Do While Timer < t + duration

       DoEvents

    Loop

End Sub

 

 

 

Die oberste Schicht, bestehend aus dem Modul CollatzAnimStart, enthält nur eine simple Prozedur, welche den Animator in Gang setzt und mit Werten für die Parameter versorgt. In einer komfortab­leren Version könnte man dieses Modul durch ein Formular ersetzen, mit dessen Hilfe der Benutzer die Parameter eingeben kann.

 

‘------------------------------------

‘Module CollatzAnimStart

‘------------------------------------

 

Option Explicit

 

Public Sub startCollatzAnimation()

    Dim ca As CollatzAnimator

    Dim s(2 To 7) As Long

    Dim i As Long

    Dim w As Worksheet

   

    Set w = Worksheets("Tabelle2")

    Set ca = New CollatzAnimator

   

    For i = 2 To 7

        s(i) = i

    Next i

    w.Activate

   

    ca.doAnimation w, s, 1

   

End Sub

 

Download

Ereignisgesteuerte Animation der Collatzfolgenberechnung
event-driven animation; example: calculation of Collatz sequences
CollatzAnimation.zip
Komprimiertes Archiv im ZIP Format 21.1 KB