This example show how to create a simple drawing. It uses the 2D drawing commands to draw two sine waves at different frequencies and shows the harmonic produced by combining the two waves. It uses procedures, which we will discuss in more detail later on, to break the drawing tasks into three self-contained tasks.
Drawing the axes - demonstrates the Line command.
Drawing the legend - demonstrates the Box and DrawText commands.
Drawing the wave forms - demonstrates the LineXY command and shows how to use color.
Code: Select all
; Form.
Enumeration
#wdwHarmonic
EndEnumeration
; Gadgets.
Enumeration
#txtPlot1
#cboPlot1
#txtPlot2
#cboPlot2
#imgPlot
EndEnumeration
; Image.
Enumeration
#drgPlot
EndEnumeration
; Event variables.
Define.L Event, EventWindow, EventGadget, EventType, EventMenu
; Implementation.
Procedure CreateWindow()
; Creates the window and gadgets.
If OpenWindow(#wdwHarmonic, 450, 200, 650, 680, "Harmonics", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
; This is a non-visual gadget used to draw the image, later its contents will be displayed in #imgPlot.
CreateImage(#drgPlot, 640, 640, 24)
; Label for the Plot 1 combo.
TextGadget(#txtPlot1, 2, 5, 40, 20, "Plot 1:")
; The Plot 1 combo.
ComboBoxGadget(#cboPlot1, 45, 5, 150, 20)
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)")
; Select Sin(X)
SetGadgetState(#cboPlot1, 0)
; Label for the Plot 1 combo.
TextGadget(#txtPlot2, 210, 5, 40, 20, "Plot 2:")
; The Plot 1 combo.
ComboBoxGadget(#cboPlot2, 255, 5, 150, 20)
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)")
; Select Sin(X * 2), otherwise the initial display is a bit uninteresting.
SetGadgetState(#cboPlot2, 1)
; The visual image gadget on the window.
ImageGadget(#imgPlot, 2, 30, 646, 616, 0, #PB_Image_Border)
EndIf
EndProcedure
Procedure PlotAxes()
; Draws the axes on the image #drgPlot.
; Send drawing commands to #drgPlot.
StartDrawing(ImageOutput(#drgPlot))
; Draw a white background.
Box(0, 0, ImageWidth(#drgPlot), ImageHeight(#drgPlot), #White)
; Draw the axes in black.
Line(1, 1, 1, ImageHeight(#drgPlot) - 2, #Black)
Line(1, (ImageHeight(#drgPlot) - 2) /2, ImageWidth(#drgPlot) -2, 1, #Black)
; Finished drawing.
StopDrawing()
EndProcedure
Procedure PlotLegend(alngPlot1, alngPlot2)
; Draws the legend on the image #drgPlot.
Protected.S strFunc1, strFunc2, strLabel1, strLabel2, strLabel3
; Set label text 1.
If alngPlot1 = 0
strFunc1 = "Sin(X)"
Else
strFunc1 = "Sin(X * " + StrU(alngPlot1 + 1) + ")"
EndIf
; Set label text 2.
If alngPlot2 = 0
strFunc2 = "Sin(X)"
Else
strFunc2 = "Sin(X * " + StrU(alngPlot2 + 1) + ")"
EndIf
; Set label text.
strLabel1 = "Y = " + strFunc1
strLabel2 = "Y = " + strFunc2
strLabel3 = "Y = " + strFunc1 + " + " + strFunc2
; Draw legend.
StartDrawing(ImageOutput(#drgPlot))
; Box.
DrawingMode(#PB_2DDrawing_Outlined)
Box(20, 10, TextWidth(strLabel3) + 85, 80, #Black)
; Label 1.
Line(30, 30, 50, 1, #Blue)
DrawText(95, 22, strLabel1, #Black, #White)
; Label 2.
Line(30, 50, 50, 1, #Green)
DrawText(95, 42, strLabel2, #Black, #White)
; Label 3.
Line(30, 70, 50, 1, #Red)
DrawText(95, 62, strLabel3, #Black, #White)
StopDrawing()
EndProcedure
Procedure PlotFunction(alngPlot1, alngPlot2)
; Draws the waveforms on the image #drgPlot.
Protected.L lngSX, lngEX
Protected.F fltRad1, fltRad2, fltSY1, fltEY1, fltSY2, fltEY2, fltSY3, fltEY3
StartDrawing(ImageOutput(#drgPlot))
; Set initial start points for each wave.
lngSX = 1
fltSY1 = ImageHeight(#drgPlot) / 2
fltSY2 = fltSY1
fltSY3 = fltSY1
; Plot wave forms.
For lngEX = 1 To 720
; Sine function works in radians, so convert from degrees and calculate sine.
; Function 1
If alngPlot1 = 0
fltRad1 = Sin(Radian(lngEX))
Else
; If the function should have a multiplier, account for this.
fltRad1 = Sin(Radian(lngEX) * (alngPlot1 + 1))
EndIf
; Function 2
If alngPlot2 = 0
fltRad2 = Sin(Radian(lngEX))
Else
fltRad2 = Sin(Radian(lngEX) * (alngPlot2 + 1))
EndIf
; Plot function 1 in blue.
; Calculate end Y point.
fltEY1 = (ImageHeight(#drgPlot) / 2) + (fltRad1 * 100)
; Draw a line from the start point to the end point.
LineXY(lngSX, fltSY1, lngEX, fltEY1, #Blue)
; Update the next start Y point to be the current end Y point.
fltSY1 = fltEY1
; Plot function 2 in green.
fltEY2 = (ImageHeight(#drgPlot) / 2) + (fltRad2 * 100)
LineXY(lngSX, fltSY2, lngEX, fltEY2, #Green)
fltSY2 = fltEY2
; Plot harmonic in red.
fltEY3 = (ImageHeight(#drgPlot) / 2) + ((fltRad1 + fltRad2) * 100)
LineXY(lngSX, fltSY3, lngEX, fltEY3, #Red)
fltSY3 = fltEY3
; Update the start X point to be the current end X point.
lngSX = lngEX
Next lngEX
StopDrawing()
EndProcedure
;- Main
CreateWindow()
PlotAxes()
PlotLegend(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2))
PlotFunction(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2))
; Reload the image gadget now drawing is complete.
ImageGadget(#imgPlot, 2, 30, 646, 616, ImageID(#drgPlot), #PB_Image_Border)
;- Event loop
Repeat
Event = WaitWindowEvent()
EventWindow = EventWindow()
EventGadget = EventGadget()
EventType = EventType()
Select Event
Case #PB_Event_Gadget
If EventGadget = #txtPlot1 Or EventGadget = #txtPlot2
; Do nothing.
ElseIf EventGadget = #imgPlot
; Do nothing.
ElseIf EventGadget = #cboPlot1 Or EventGadget = #cboPlot2
; If one of the combo boxes changed, redraw the image.
PlotAxes()
PlotLegend(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2))
PlotFunction(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2))
ImageGadget(#imgPlot, 2, 30, 646, 616, ImageID(#drgPlot), #PB_Image_Border)
EndIf
Case #PB_Event_CloseWindow
If EventWindow = #wdwHarmonic
CloseWindow(#wdwHarmonic)
Break
EndIf
EndSelect
ForEver