dcsimg
 

Optical Illusions and .NET

by Hannes DuPreez
Optical Illusions and .NET

Explore creating fun and useful optical illusions.

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 Tuesday May 19th 2020
Home
Mobile Site | Full Site