Optical Illusions and .NET

Introduction

Today, you will be making a fun little project that is built as an optical illusion. Example code is in VB.NET.

Optical Illusions

An optical illusion, or visual illusion, is caused by a human’s visual system and characterized by a visual percept that differs from reality. Optical illusions can be classified into the following categories:

  • Physical
  • Physiological
  • Cognitive

Each of these contain the following properties or kinds:

  • Ambiguities
  • Distortions
  • Paradoxes
  • Fictions

The following is a list of the most popular optical illusions that can be found and created.

Creating an Optical Illusion through a VB.NET Program

Create a new Visual Basic Windows Forms application. Make the form nice and big. Add a timer control and a numeric updown on the form (you can name them anything you like). Set the Min property for the NumericUpDown control to 1 and its Max property to 10. Enable the Timer and set its Interval property to 50.

The Code

As always, let’s start with the imports. Add the following Imports statement to your code to import the Drawing2D library from the Drawing namespace. This gives us the ability to draw and colorize shapes.

Imports System.Drawing.Drawing2D

Create a variable that holds the current degrees.

   Private snDegree As Single

Add the Tick event for the Timer. This event adds a number to the current degree and if it gets to 360, it starts over. Also, add the Paint event for the form where all the drawing will take place.

   Private Sub tmrRotate_Tick(sender As Object, e As EventArgs) _
      Handles tmrRotate.Tick

      snDegree += 4

      If snDegree > 360 Then snDegree -= 360

      Invalidate()

   End Sub

   Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) _
      Handles MyBase.Paint

      Dim snWidth As Single = CSng(ClientSize.Width / 2)
      Dim snHeight As Single = CSng(ClientSize.Height / 2)

      Dim snRadius As Single = snHeight / (14 - nudRotate.Value)
      Dim snRotate As Integer = CInt(snHeight * 0.7)

      Dim iX As Integer
      Dim iAngle As Integer

      With e.Graphics

         .Clear(Color.Black)

         .SmoothingMode = SmoothingMode.AntiAlias

         .DrawEllipse(New Pen(Color.Red, 6), CInt(snWidth - _
            (snRotate * 0.95)), CInt(snHeight - (snRotate * 0.95)), _
            CInt(1.95 * snRotate), CInt(1.95 * snRotate))
         .DrawEllipse(New Pen(Color.Orange, 2), snWidth - snRotate, _
            snHeight - snRotate, 2 * snRotate, 2 * snRotate)

         For iAngle = 0 To 320 Step 40

            .ResetTransform()
            .TranslateTransform(snWidth, snHeight)
            .RotateTransform(iAngle)

            iX = CInt(0.8 * snWidth * Math.Cos((iAngle + snDegree) _
               / 57.5))

            CreateLine(e.Graphics, iX, Color.Gray)

         Next

         For iAngle = 0 To 320 Step 4

            .ResetTransform()
            .TranslateTransform(snWidth, snHeight)
            .RotateTransform(iAngle)

            iX = CInt(0.8 * snWidth * Math.Cos((iAngle + snDegree) _
               / 57.5))

            CreateSphere(e.Graphics, snRadius, 180 - iAngle, iX, _
               0, Color.SteelBlue)

         Next

         .ResetTransform()

      End With

   End Sub

Lastly, add the procedures that add the connecting lines and the spheres.

   Private Sub CreateLine(g As Graphics, x As Single, col As Color)

      g.DrawLine(New Pen(Color.White, 5), -80, -1, x, -1)
      g.DrawLine(New Pen(col, 4), -80, 0, x, 0)

   End Sub

   Private Sub CreateSphere(g As Graphics, rad As Single, _
      rot As Single, x1 As Single, y1 As Single, col As Color)

      If rot <> 0 Then

         Dim m As Matrix = g.Transform
         m.RotateAt(rot, New PointF(x1, y1))
         g.Transform = m
         m.Dispose()

      End If

      Dim gpPath As New GraphicsPath()
      Dim fRect As New RectangleF(x1 - rad, y1 - rad, 2 * rad, _
         2 * rad)

      gpPath.AddEllipse(fRect)

      fRect.X += rad / 50
      fRect.Y += rad / 50

      Using pgbBrush As New PathGradientBrush(gpPath)

         pgbBrush.CenterPoint = New PointF(x1 + rad, -10)
         pgbBrush.CenterColor = col

         Dim colors As Color() = {Color.LightGray}

         pgbBrush.SurroundColors = colors
         g.FillPath(pgbBrush, gpPath)

         pgbBrush.CenterColor = Color.FromArgb(10, Color.LightGray)
         fRect.Width *= 0.2F
         fRect.Height *= 0.2F
         fRect.Offset(rad / 3, rad / 2)
         g.FillEllipse(pgbBrush, fRect)

      End Using

   End Sub

Running your application will result in an optical illusion that looks like Figure 1.

Optical Illusion
Figure 1: Optical Illusion

Conclusion

I hope you had fun today and I hope further that I will be able to make another project such as this is the near future. Until then, happy coding!

Hannes DuPreez
Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read