Have you ever tried to draw a sine wave and it has been harder than what you thought? This example shows how to create a sine wave that can have its parameters changed at runtime and then the updated version of the wave can be seen in the program.

Figure 1. Screen grab of running program

Screen Grab

The formula for generating a sine wave is y = A*sin(B(x-C))+D. Where A is the amplitude of the wave, B is the frequency of the wave, x is the x-axis value, C is the y-axis shift, and D is the vertical shift. This is good when calculating values on a piece of paper, and it becomes a little more challenging when doing this in a computer program.

Drawing with pixels can be a little tricky, and to make it easier for longer waves, the example uses drawing a line instead, which has the added benefit of preventing spaces between points on a wave. The method which makes the math and drawing concepts work is called DrawWavyLine.

 

Public Sub DrawWavyLine(g as Graphics, XStart as Double, YLength as double, Amp as double, Period as Double, YStart as Double)
//y = asin(b(x-h))+k
//a = amplitude, b = period, h = horizontal shift, k = vertical shift, x = x-axis
//XStart=Starting pixel coordinate on x-axis
//YLength=Total length of the wave in pixels
//Amplitude=Height of the wave from the middle to top of the wave in pixels
//Period=Length of the repeating wave(not sure of the units and is a function of sine)
//YStart=Starting pixel coordinate on the y-axis

Dim i as integer
For i = 0 to YLength
g.ForeColor = RGB(255,0,0) //Red
g.DrawLine(i+XStart, Amp*sin(Period*(i))+YStart, i+1+XStart, Amp*sin(Period*(i+1))+YStart)
Next i

//Draw a border
g.ForeColor = RGB(0,0,0) //Black
g.DrawRect(0,0,g.Width, g.Height)
End Sub

 

A For-Next loop will repetitively go through each point in the wave through its entire length. DrawLine is a method built-into Xojo and draws a line from X1,Y1 to X2,Y2. To shift the starting point of the wave, the XStart value is added to the X1 and X2 values. Calculating Y values implements the wave amplitude (amp) the sine of the period (kind of frequency) and the value in the loop. YStart is the y-axis offset of the sine wave graph.

Figure 2. Sine Wave Parameters

Sine Wave Parameters

 

There are five labels and five textbox controls added, along with a button. Initial values for each of the five textbox controls have been added so that a wave will appear when the update button is pressed. Code in the update button is one line.

 

Sub Action() Handles Action

  //update the Canvas

  Canvas1.Invalidate

End Sub

 

Drawing in a Canvas control should occur in the Paint event, and the code is shown below.

 

Sub Paint(g As Graphics, areas() As REALbasic.Rect) Handles Paint

  Dim XStart1, Y1, YStart1, Amp1, Per1 as Double

  XStart1 = Val(TFX.Text)

  Y1 = Val(TFY.Text)

  Amp1 = Val(TFAmplitude.Text)

  Per1 = Val(TFPeriod.Text)

  YStart1 = Val(TFYStart.Text)

 

  Call DrawWavyLine(g, XStart1, Y1, Amp1, Per1, YStart1)

End Sub

 

Five double-type variables are created and values from the respective textfield’s are converted to a numerical value from a text value by using the Val method. DrawWavyLine is then called with the updated values and a sine wave is shown.

Here is the example Xojo project that you can have fun with the code. SineWave.xojo_binary_project

Here is the example C++/CLI example project C++/CLISineWave.zip

 A method was also created to make a vertical sine wave, and a modified version of the program makes the following wave.

Figure 3. Vertical Sine Wave

Vertical Sine Wave

 

The Xojo program for drawing the vertical sine wave can be downloaded here: Vertical Sine Wave. Code for the example is very similar, and the following method is where drawing happens:

Public Sub DrawWavyLineVertical(g as Graphics, XStart as Double, XLength as double, Amp as double, Period as Double, YStart as Double)
//y = asin(b(x-h))+k
//a = amplitude, b = period, h = horizontal shift, k = vertical shift, x = x-axis
Dim s as RGBSurface

Dim i as integer
For i = 0 to XLength
g.ForeColor = RGB(0,0,255) //blue
g.DrawLine(Amp*sin(Period*(i))+XStart, i+YStart, Amp*sin(Period*(i+1))+XStart, i+1+YStart)
Next i

//Draw a border
g.ForeColor = RGB(0,0,0) //black
g.DrawRect(0,0,g.Width, g.Height)
End Sub

 

 

 

This example was created on Windows 10 with Xojo 2019 r1.1 on 26 June 2019, and edited on 28 June 2019