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.
- Afterimage
- Ambiguous image
- Ames trapezoid window
- Autokinetic effect
- Autostereogram
- Barberpole illusion
- Benham’s top
- Beta movement
- Bezold Effect
- Blivet
- Café wall illusion
- Catoptric cistula
- Checker shadow illusion
- Chubb illusion
- Color constancy
- Contingent perceptual aftereffect
- Convergence micropsia
- Cornsweet illusion
- Delboeuf illusion
- Disappearing Model
- Ebbinghaus illusion
- Ehrenstein illusion
- Fechner color
- Figure-ground (perception)
- Filling-in
- Flash lag illusion
- Forced perspective
- Fraser spiral illusion
- Gravity hill
- Grid illusion
- Hering illusion
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.
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!