Einsteiger-Kapitel - Anzeigen von Grafik-Ausgabe & einfaches Zeichnen
Dieses Beispiel zeigt, wie man eine einfache Zeichnung erstellt. Es verwendet die 2D Zeichenbefehle zum Zeichnen von zwei Sinuskurven mit verschiedenen Frequenzen und zeigt die durch die Kombination der beiden Wellen hergestelte "Harmonie". Es verwendet Prozeduren, welche wir uns später im Detail anschauen werden, um die Zeichenaufgaben in drei in sich abgeschlossene Aufgaben aufzuteilen: ; Fenster
Enumeration
#WinHarmonic
EndEnumeration
; Gadgets
Enumeration
#txtPlot1
#cboPlot1
#txtPlot2
#cboPlot2
#imgPlot
EndEnumeration
; Bild (Image)
Enumeration
#drgPlot
EndEnumeration
; Die Bild-Abmessungen werden an verschiedenen Stellen zum Definieren weiterer Werte genutzt.
#imgPlotX = 8
#imgPlotY = 40
#imgPlotW = 745
#imgPlotH = 645
; Ereignis-Variablen
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
; Implementierung
Procedure CreateWindow()
; Erstellt das Fenster und die Gadgets.
If OpenWindow(#WinHarmonic, 30, 30, #imgPlotW + 20, #imgPlotH + 55, "Harmonics", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar)
; Dies ist ein nicht sichtbares Image, welches zum Zeichnen des Bildes verwendet wird,
; später wird sein Inhalt in #imgPlot dargestellt.
CreateImage(#drgPlot, #imgPlotW - 5, #imgPlotH - 5, 24)
; Beschriftung für die Plot 1 Auswahlbox.
TextGadget(#txtPlot1, 2, 5, 50, 25, "Plot 1:")
; Die Plot 1 Auswahlbox.
ComboBoxGadget(#cboPlot1, 55, 5, 150, 25)
AddGadgetItem(#cboPlot1, 0, "Sin(X)")
AddGadgetItem(#cboPlot1, 1, "Sin(X * 2)")
AddGadgetItem(#cboPlot1, 2, "Sin(X * 3)")
AddGadgetItem(#cboPlot1, 3, "Sin(X * 4)")
AddGadgetItem(#cboPlot1, 4, "Sin(X * 5)")
AddGadgetItem(#cboPlot1, 5, "Sin(X * 6)")
; Auswählen von Sin(X)
SetGadgetState(#cboPlot1, 0)
; Beschriftung für die Plot 2 Auswahlbox.
TextGadget(#txtPlot2, 230, 5, 50, 25, "Plot 2:")
; Die Plot 2 Auswahlbox.
ComboBoxGadget(#cboPlot2, 280, 5, 150, 25)
AddGadgetItem(#cboPlot2, 0, "Sin(X)")
AddGadgetItem(#cboPlot2, 1, "Sin(X * 2)")
AddGadgetItem(#cboPlot2, 2, "Sin(X * 3)")
AddGadgetItem(#cboPlot2, 3, "Sin(X * 4)")
AddGadgetItem(#cboPlot2, 4, "Sin(X * 5)")
AddGadgetItem(#cboPlot2, 5, "Sin(X * 6)")
; Auswählen Sin(X * 2), andernfalls ist die anfängliche Darstellung ziemlich uninteressant.
SetGadgetState(#cboPlot2, 1)
; Das sichtbare Bild-Gadget auf dem Fenster.
ImageGadget(#imgPlot, #imgPlotX, #imgPlotY, #imgPlotW, #imgPlotH, 0, #PB_Image_Border)
EndIf
EndProcedure
Procedure PlotAxes()
; Zeichnet die Achsen auf dem Bild #drgPlot.
; Sendet Zeichenbefehle an #drgPlot.
StartDrawing(ImageOutput(#drgPlot))
; Zeichnet einen weißen Hintergrund.
Box(0, 0, ImageWidth(#drgPlot), ImageHeight(#drgPlot), RGB(255, 255, 255))
; Zeichnet die Achsen in schwarz.
Line(1, 1, 1, ImageHeight(#drgPlot) - 2, RGB(0, 0, 0))
Line(1, (ImageHeight(#drgPlot) - 2) /2, ImageWidth(#drgPlot) -2, 1, RGB(0, 0, 0))
; Zeichnen abschließen.
StopDrawing()
EndProcedure
Procedure PlotLegend(alngPlot1, alngPlot2)
; Zeichnet die Legende auf dem Bild #drgPlot.
Protected.s strFunc1, strFunc2, strLabel1, strLabel2, strLabel3
; Legt den Beschriftungs-Text 1 fest.
If alngPlot1 = 0
strFunc1 = "Sin(X)"
Else
strFunc1 = "Sin(X * " + StrU(alngPlot1 + 1) + ")"
EndIf
; Legt den Beschriftungs-Text 2 fest.
If alngPlot2 = 0
strFunc2 = "Sin(X)"
Else
strFunc2 = "Sin(X * " + StrU(alngPlot2 + 1) + ")"
EndIf
; Legt den Beschriftungs-Text fest.
strLabel1 = "Y = " + strFunc1
strLabel2 = "Y = " + strFunc2
strLabel3 = "Y = " + strFunc1 + " + " + strFunc2
; Zeichnet die Legende.
StartDrawing(ImageOutput(#drgPlot))
; Box.
DrawingMode(#PB_2DDrawing_Outlined)
Box(20, 10, TextWidth(strLabel3) + 85, 80, RGB(0, 0, 0))
; Beschriftung 1.
Line(30, 30, 50, 1, RGB(0, 0, 255))
DrawText(95, 22, strLabel1, RGB(0, 0, 0), RGB(255, 255, 255))
; Beschriftung 2.
Line(30, 50, 50, 1, RGB(0, 255, 200))
DrawText(95, 42, strLabel2, RGB(0, 0, 0), RGB(255, 255, 255))
; Beschriftung 3.
Line(30, 70, 50, 1, RGB(255, 0, 0))
DrawText(95, 62, strLabel3, RGB(0, 0, 0), RGB(255, 255, 255))
StopDrawing()
EndProcedure
Procedure PlotFunction(alngPlot1, alngPlot2)
; Zeichnet die Wellenformen auf das Bild #drgPlot.
Protected.l lngSX, lngEX
Protected.f fltRad1, fltRad2, fltSY1, fltEY1, fltSY2, fltEY2, fltSY3, fltEY3
StartDrawing(ImageOutput(#drgPlot))
; Legt die anfänglichen Start-Punkte für jede Welle fest.
lngSX = 1
fltSY1 = ImageHeight(#drgPlot) / 2
fltSY2 = fltSY1
fltSY3 = fltSY1
; Zeichnet die Wellenformen.
For lngEX = 1 To 720
; Die Sinus-Funktion arbeitet im Bogenmaß, daher konvertieren von Grad und berechnen den Sinus.
; Funktion 1
If alngPlot1 = 0
fltRad1 = Sin(Radian(lngEX))
Else
; Wenn die Funktion einen Multiplikator haben sollte, beachten wir dies.
fltRad1 = Sin(Radian(lngEX) * (alngPlot1 + 1))
EndIf
; Funktion 2
If alngPlot2 = 0
fltRad2 = Sin(Radian(lngEX))
Else
fltRad2 = Sin(Radian(lngEX) * (alngPlot2 + 1))
EndIf
; Zeichnen der Funktion 1 in blau.
; Berechnen des Y Endpunkts.
fltEY1 = (ImageHeight(#drgPlot) / 2) + (fltRad1 * 100)
; Zeichnen einer Linie vom Startpunkt zum Endpunkt.
LineXY(lngSX, fltSY1, lngEX, fltEY1, RGB(0, 0, 255))
; Aktualisieren des nächsten Y Startpunkts, damit dieser den aktuellen Y Endpunkt übernimmt.
fltSY1 = fltEY1
; Zeichnen der Funktion 2 in grün.
fltEY2 = (ImageHeight(#drgPlot) / 2) + (fltRad2 * 100)
LineXY(lngSX, fltSY2, lngEX, fltEY2, RGB(0, 255, 200))
fltSY2 = fltEY2
; Zeichnen der Harmonie in rot.
fltEY3 = (ImageHeight(#drgPlot) / 2) + ((fltRad1 + fltRad2) * 100)
LineXY(lngSX, fltSY3, lngEX, fltEY3, RGB(255, 0, 0))
fltSY3 = fltEY3
; Aktualisieren des X Startpunkts, damit dieser den aktuellen X Endpunkt übernimmt.
lngSX = lngEX
Next lngEX
StopDrawing()
EndProcedure
;- Main
CreateWindow()
PlotAxes()
PlotLegend(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2))
PlotFunction(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2))
; Neu laden des Image Gadgets, da das Zeichnen nun komplett ist.
ImageGadget(#imgPlot, #imgPlotX, #imgPlotY, #imgPlotW, #imgPlotH, ImageID(#drgPlot), #PB_Image_Border)
;- Ereignis-Schleife
Repeat
Event = WaitWindowEvent()
EventWindow = EventWindow()
EventGadget = EventGadget()
EventType = EventType()
Select Event
Case #PB_Event_Gadget
If EventGadget = #txtPlot1 Or EventGadget = #txtPlot2
; Tue nichts.
ElseIf EventGadget = #imgPlot
; Tue nichts.
ElseIf EventGadget = #cboPlot1 Or EventGadget = #cboPlot2
; Wenn eine der Auswahlboxen verändert wurde, zeichnen wir das Bild erneut.
PlotAxes()
PlotLegend(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2))
PlotFunction(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2))
ImageGadget(#imgPlot, #imgPlotX, #imgPlotY, #imgPlotW, #imgPlotH, ImageID(#drgPlot), #PB_Image_Border)
EndIf
Case #PB_Event_CloseWindow
If EventWindow = #WinHarmonic
CloseWindow(#WinHarmonic)
Break
EndIf
EndSelect
ForEver
Einsteiger-Kapitel Navigation
< Vorheriges: Erstellen einer grafischen Benutzeroberfläche (GUI) | Überblick | Nächstes: Strukturieren von Programmcode in Prozeduren >