Trigonometry and .NET


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!


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


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


   bool Wave;
   bool Circle;

   float Delta = 0;
   int X = 0;


   Dim Wave As Boolean
   Dim Circle As Boolean

Add the code for the buttons:


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


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



   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:


   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.TextRenderingHint =

                  for (var i = 1; i <= strMarquee.Length; i++)
                     if (Wave)
                        Xx = X + (i * 27);
                        Yy = 75 + (float)(20 * Math.Cos(Xx /
                        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.RotateTransform(d + 100);

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

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




   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, _

         Using g As Graphics = Graphics.FromImage(bmpMarquee)

            With g

               .TextRenderingHint = _

               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)

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

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

                  End If


               picCanvas.Image = bmpMarquee.Clone


            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


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!

This article was originally published on July 26th, 2018

About the Author

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 and Bpb Publications.

You could reach him at: ojdupreez1978[at]gmail[dot]com

Related Articles

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date