dcsimg

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!



This article was originally published on May 19th, 2020

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