 Trigonometry and .NET

WEBINAR:On-Demand

Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame

Introduction

Hello, and welcome to today's installment of my math-related articles that I have been doing for the past few months. As you know, I have become a math nerd by chance and haven't had formal training. Yes, I did math in school, but let's not talk about that today!

Trigonometry

The word trigonometry originates from the Greek trigōnon ("triangle") and metron ("measure"). Trigonometry is a branch of mathematics that studies relationships involving lengths and angles of triangles.

Trigonometric Functions

The most familiar trigonometric functions are as follows:

• sine: The sine of an angle is the ratio of the length of the opposite side to the length of the hypotenuse
• cosine: The cosine of an angle is the ratio of the length of the adjacent side to the length of the hypotenuse
• tangent: The tangent of an angle is the ratio of the length of the opposite side to the length of the adjacent side
• cotangent: The cotangent of an angle is the reciprocal of its tangent (the ratio of the length of the adjacent side to the length of the opposite side)
• secant: The secant of an angle is the reciprocal of its cosine (the ratio of the length of the hypotenuse to the length of the adjacent side)
• cosecant: The cosecant of an angle is the reciprocal of its sine (the ratio of the length of the hypotenuse to the length of the opposite side)

Stop me before I get into formulas…

Our Project

Today's project will demonstrate the three more popular trigonometric functions (sine, cosine, tangent) to draw circles and waves. Hopefully, in a follow-up article, I can delve deeper into the cotangent, secant, and cosecant functions.

Start Visual Studio and create either a C# or Visual Basic Windows Forms project.

Once the project has loaded, design your form as shown in Figure 1. Make sure of the following at design time:

• Your PictureBox is quite big
• Your PictureBox is Docked completely
• Your PictureBox has a background color
• You have a Timer
• The Timer is Enabled
• The Timer's Interval is set to a relatively small number
• You have two buttons: one labeled 'Circle' and the other labeled 'Wave'
• You keep in mind that my object names might differ from yours Figure 1: Design

Code

Add two Boolean fields to keep track of which button was clicked.

C#

bool Wave;
bool Circle;

float Delta = 0;
int X = 0;

VB.NET

Dim Wave As Boolean
Dim Circle As Boolean

Add the code for the buttons:

C#

private void btnWaveMarquee_Click(object sender, EventArgs e)
{
Wave = true;
Circle = false;

}

private void btnCircleMarquee_Click(object sender, EventArgs e)
{
Circle = true;
Wave = false;

}

VB.NET

Private Sub btnWaveMarquee_Click(sender As Object, e As _
EventArgs) Handles btnWaveMarquee.Click

Wave = True
Circle = False

End Sub

Private Sub btnCircleMarquee_Click(sender As Object, e As _
EventArgs) Handles btnCircleMarquee.Click

Circle = True
Wave = False

End Sub

In each button, you set the corresponding flag to True. This is so that we can make use of a simple If statement inside the Timer's Tick event to draw the correct effect.

Add the Timer's code:

C#

private void tmrTime_Tick(object sender, EventArgs e)
{

string strMarquee = "I love Trig!";

double Xx;
double Yy;

X = -(strMarquee.Length * 20 + 25);

X += 3;

if (X > ClientSize.Width)
X = -(strMarquee.Length * 20 + 25);

Delta += 2;
if (Delta > picCanvas.Width)
Delta = 0;

using (Bitmap bmpMarquee = new
Bitmap(this.ClientSize.Width, this.ClientSize.Height))
{
using (Graphics g = Graphics.FromImage(bmpMarquee))
{
{
var withBlock = g;
withBlock.Clear(Color.Black);
withBlock.TextRenderingHint =
System.Drawing.Text.TextRenderingHint
.AntiAlias;

for (var i = 1; i <= strMarquee.Length; i++)
{
if (Wave)
{
Xx = X + (i * 27);
Yy = 75 + (float)(20 * Math.Cos(Xx /
(double)29));
g.DrawString(strMarquee.Substring(1, i),
new Font("Tahoma", 20), Brushes.Green,
(float)Xx, (float)Yy);
}
else if (Circle)
{
float Radius = 100;
float d = Delta + (i * 19);

Xx = (Radius * Math.Cos(d / 71.23)) +
(this.ClientSize.Width / (double)2);
Yy = (Radius * Math.Sin(d / 71.23)) +
(this.ClientSize.Height / (double)2);

withBlock.ResetTransform();
withBlock.TranslateTransform((float)Xx,
(float)Yy);
withBlock.RotateTransform(d + 100);
withBlock.TranslateTransform((float)-Xx,
(float)-Yy);

withBlock.DrawString(strMarquee
.Substring(1, i),
new Font("Tahoma", 20), Brushes.Blue,
(float)Xx, (float)Yy);
}
}

picCanvas.Image = (Image)bmpMarquee.Clone();

picCanvas.Invalidate();
}
}
}

}

VB.NET

Private Sub tmrTime_Tick(sender As Object, e As EventArgs) _
Handles tmrTime.Tick

Dim strMarquee As String = "I love Trig!"

Dim Xx As Single
Dim Yy As Single

Static X As Integer = -(strMarquee.Length * 20 + 25)
Static Delta As Single

X += 3

If X > ClientSize.Width Then X = -(strMarquee.Length * _
20 + 25)

Delta += 2
If Delta > picCanvas.Width Then Delta = 0

Using bmpMarquee As Bitmap = New _
Bitmap(Me.ClientSize.Width, _
Me.ClientSize.Height)

Using g As Graphics = Graphics.FromImage(bmpMarquee)

With g

.Clear(Color.Black)
.TextRenderingHint = _
Drawing.Text.TextRenderingHint.AntiAlias

For i = 1 To strMarquee.Length

If Wave Then

Xx = X + (i * 27)
Yy = 75 + (20 * Math.Cos(Xx / 29))
g.DrawString(Mid(strMarquee, i, 1), New _
Font("Tahoma", 20), Brushes.Green, Xx, Yy)

ElseIf Circle Then

Dim Radius As Single = 100
Dim d As Single = Delta + (i * 19)

Xx = (Radius * Math.Cos(d / 71.23)) + _
(Me.ClientSize.Width / 2)
Yy = (Radius * Math.Sin(d / 71.23)) + _
(Me.ClientSize.Height / 2)

.ResetTransform()
.TranslateTransform(Xx, Yy)
.RotateTransform(d + 100)
.TranslateTransform(-Xx, -Yy)

.DrawString(Mid(strMarquee, i, 1), New _
Font("Tahoma", 20), Brushes.Blue, Xx, Yy)

End If

Next

picCanvas.Image = bmpMarquee.Clone

picCanvas.Invalidate()

End With

End Using

End Using

End Sub

First, you need the width of the canvas. The canvas in this case is obviously the PictureBox. You then create an in-memory graphics object with which to draw. Making use of the in-memory graphics object, you create a string with the font style and color and text to draw, depending on which button was clicked.

After all the objects are set up, you make use of the Cos and Sin methods inside the System.Math namespace to draw the string you created earlier in the Wave form or in Circle form. Because the calculations happen inside the Timer's Tick event, the string continuously loops according to the desired shape.

Figures 2 and 3 show the results. Figure 2: Circle Figure 3: Wave

Conclusion

In today's article, you have learned about trigonometry in general as well as how to make use of the sine, cosine, and tangent functions to create funky, loopy text. I hope you have enjoyed this article. Hopefully, in another installment, I can speak about cotangent, secant, and cosecant functions. Until then, happy coding!

Hannes DuPreez

Hannes du Preez is a self-taught developer who started learning to program in the days of QBasic. He has written several articles over the years detailing his programming quests and adventures. .NET is his second love, just after his wife and kid. He has always been an avid supporter of .NET since the beginning and is an expert in VB and C#. He was given the Microsoft Most Valuable Professional Award for .NET (2008–2017). He has worked as a moderator and an article reviewer on online forums and currently works as a C# developer and writes articles for CodeGuru.com, Developer.com, DevX.com, and the Database journal. His first book, Visual Studio 2019 in Depth... is currently on sale on Amazon.com.

Most Popular Programming Stories

• There have been no articles posted today.