The Amazing Visual Magic! Drawing the “Rotating Snake” Optical Illusion with C++

Have you ever seen a still image that creates the illusion of dynamic rotation? Today, we will unveil the mystery behind this amazing “Rotating Snake” optical illusion and guide you step by step on how to implement it using C++ code!

Unveiling the Principle of the Illusion

The secret of the “Rotating Snake” illusion lies in the time difference in how the human brain processes different color contrasts. High-contrast colors (like black and white) are processed much faster than low-contrast colors (like red and cyan). This difference in processing time creates the effect of relative motion in a still image, resulting in the illusion of rotation.

Below is an image of the “Rotating Snake”. Does it seem to be moving?

The Amazing Visual Magic! Drawing the "Rotating Snake" Optical Illusion with C++

1. Basic Construction: Drawing Sector Units

The “Rotating Snake” illusion image is composed of different colored sectors.

First, we need to master the basic drawing functions. The <span><span>solidpie()</span></span> function from the EasyX graphics library can be used to draw filled sectors:

setfillcolor(RGB(R, G, B));  // Set fill color
solidpie(left, top, right, bottom, start_angle, end_angle);

1. The <span><span>setfillcolor()</span></span> function sets the fill color. The RGB (Red, Green, Blue) color model uses three components to represent color, with each component ranging from 0 to 255:

  • RGB(0,0,0) represents black
  • RGB(255,255,255) represents white
  • RGB(255,0,0) represents pure red

The Amazing Visual Magic! Drawing the "Rotating Snake" Optical Illusion with C++2. The <span><span>solidpie()</span></span> function

  • (left, top): Coordinates of the top-left corner of the bounding rectangle
  • (right, bottom): Coordinates of the bottom-right corner of the bounding rectangle
  • start_angle: Starting angle of the sector (in radians)
  • end_angle: Ending angle of the sector (in radians)

Angle calculation: The code uses expressions like 2*PI/60 because: a complete circle = 2π radians = 360°, and each sector unit occupies 1/60 of the circle, which is 6°, thus 2*PI/60 represents the radian value corresponding to 6°.

#include<graphics.h>  // Graphics library header file, provides drawing functions
#include<conio.h>     // Console input/output header file, provides _getch() function
#include<stdio.h>     // Standard input/output header file
// Main function: program entry point
int main(){
    float PI = 3.14159;  // Define the approximate value of π
    initgraph(600, 600);  // Create a 600x600 pixel graphics window
    setbkcolor(RGB(128, 128, 128));  // Set background color to medium gray
    cleardevice();  // Clear the entire canvas with the background color
    // Define center and radius parameters
    int centerX = 300, centerY = 300;  // Center coordinates (300,300), located at the center of the window
    int radius = 200;  // Circle radius of 200 pixels
    // Calculate bounding rectangle coordinates for the sector
    int left = centerX - radius;   // Top-left x coordinate of the bounding rectangle
    int top = centerY - radius;    // Top-left y coordinate of the bounding rectangle
    int right = centerX + radius;  // Bottom-right x coordinate of the bounding rectangle
    int bottom = centerY + radius; // Bottom-right y coordinate of the bounding rectangle
    // Draw cyan sector
    setfillcolor(RGB(0, 240, 220));  // Set fill color to cyan
    solidpie(left, top, right, bottom, 0, 2*PI/60);  // Draw sector from 0° to 6°
    // Draw white sector
    setfillcolor(RGB(255, 255, 255));  // Set fill color to white
    solidpie(left, top, right, bottom, 2*PI/60, 3*PI/60);  // Draw sector from 6° to 9°
    // Draw red sector
    setfillcolor(RGB(200, 0, 0));  // Set fill color to dark red
    solidpie(left, top, right, bottom, 3*PI/60, 5*PI/60);  // Draw sector from 9° to 15°
    // Draw black sector
    setfillcolor(RGB(0, 0, 0));  // Set fill color to black
    solidpie(left, top, right, bottom, 5*PI/60, 6*PI/60);  // Draw sector from 15° to 18°
    // Pause the program, waiting for user input
    _getch();  // Pause program execution, waiting for keyboard input
    return 0;  // Program exits normally
}

With this program, we can draw a pattern composed of four different colored sectors combined together.

The Amazing Visual Magic! Drawing the "Rotating Snake" Optical Illusion with C++

2. Using for Loop: Copying Sector Units

To achieve a complete disc effect, we need to combine multiple sector units from above. Using a for loop can help us easily replicate multiple sector units:

// Use for loop to draw 20 groups of sector units, forming a complete rotating snake illusion disc
for(int i = 0; i < 20; i++)  // Loop 20 times, corresponding to the disc being divided into 20 sector units
{
    // Calculate the offset angle for the current sector group
    // PI/10 = 18°, the total angle for each group of sectors is 18°, and 20 groups perfectly cover 360°
    float offset = i * PI / 10;  // Offset angle for each group of sectors, i from 0 to 19, offset from 0° to 342°
    // Draw cyan sector - first sector area
    setfillcolor(RGB(0, 240, 220));  // Set fill color to cyan (RGB values: R=0, G=240, B=220)
    // Draw sector: angle range is [offset, offset+6°], occupying 1/60 of the circle
    solidpie(left, top, right, bottom, offset, 2*PI/60 + offset);
    // Draw white sector - second sector area
    setfillcolor(RGB(255, 255, 255));  // Set fill color to pure white
    // Draw sector: angle range is [offset+6°, offset+9°], occupying 1/120 of the circle
    solidpie(left, top, right, bottom, 2*PI/60 + offset, 3*PI/60 + offset);
    // Draw red sector - third sector area
    setfillcolor(RGB(200, 0, 0));  // Set fill color to dark red (not pure red, lower brightness)
    // Draw sector: angle range is [offset+9°, offset+15°], occupying 1/60 of the circle
    solidpie(left, top, right, bottom, 3*PI/60 + offset, 5*PI/60 + offset);
    // Draw black sector - fourth sector area
    setfillcolor(RGB(0, 0, 0));  // Set fill color to pure black
    // Draw sector: angle range is [offset+15°, offset+18°], occupying 1/120 of the circle
    solidpie(left, top, right, bottom, 5*PI/60 + offset, 6*PI/60 + offset);
    // After completing one group of sector drawings, the loop variable i increments, and the offset angle increases accordingly to draw the next group of sectors
}

After the loop ends, we have obtained a disc composed of 20 groups of sector units:The Amazing Visual Magic! Drawing the "Rotating Snake" Optical Illusion with C++

3. Advanced Effects: Multi-layer Discs and Color Changes

By nesting loops, we can create more complex effects:1. Multi-layer concentric discs: The outer loop controls the radius of the disc, drawing multiple layers of concentric discs from large to small.

// Outer loop: controls the radius of the disc, drawing multiple layers of concentric discs from large to small
for(int radius = 200; radius > 0; radius = radius - 50) // Initial radius is 200 pixels, reducing by 50 pixels each loop until the radius is greater than 0
{
    // Calculate the bounding rectangle coordinates for the current radius
    // As radius decreases, the rectangle size also shrinks, forming concentric circle effects
    int left = centerX - radius;   // Current disc bounding rectangle top-left x coordinate
    int top = centerY - radius;    // Current disc bounding rectangle top-left y coordinate
    int right = centerX + radius;  // Current disc bounding rectangle bottom-right x coordinate
    int bottom = centerY + radius; // Current disc bounding rectangle bottom-right y coordinate
    // Inner loop: draw 20 groups of sector units on each disc
    for(int i = 0; i < 20; i++)
    {
        // Draw four sectors in cyan, white, red, and black, forming the basic illusion unit
        // Each group of sectors rotates 18° relative to the previous group, covering the entire disc
    }
    // Inter-layer angle offset: after completing one disc, increase the angle offset for the next disc
    totalOffset = totalOffset + PI/20; // The angle offset between different radii is PI/20
    // This offset causes the sector patterns of different radius discs to be staggered, enhancing the three-dimensional and dynamic effect
}

After the loop ends, four concentric discs (radii 200, 150, 100, 50 pixels) will be drawn, with each disc’s sector pattern having a 9° angle offset, creating a spiraling visual effect.The Amazing Visual Magic! Drawing the "Rotating Snake" Optical Illusion with C++2. Application of the HSV Color Model

Using the HSV color model can generate richer and more colorful effects:

// Generate random hue values, ranging from 0-179 degrees
float h = rand() % 180;  // Random hue, %180 ensures the value is between 0-179
// Use HSV color model to generate complementary colors
COLORREF color1 = HSVtoRGB(h, 0.9, 0.8);        // Primary color
COLORREF color2 = HSVtoRGB(h + 180, 0.9, 0.8);  // Complementary color

HSV is a color description method that is more intuitive for humans. It defines colors through three intuitive parameters, making it easier to understand and use than the traditional RGB model.

Three elements of HSV:

  • H (Hue): Color type, ranging from 0-360°, corresponding to the position on the color wheel

  • S (Saturation): Color purity, ranging from 0-1, the higher the value, the more vivid the color

  • V (Value): Color brightness, ranging from 0-1, the higher the value, the brighter the color

Below is the complete “Rotating Snake” illusion program:

#include<graphics.h>
#include<conio.h>
#include<stdio.h>
#include<time.h>
int main(){
    // Initialization
    const float PI = 3.14159f;           // Constant for π
    initgraph(800, 600);                 // Create an 800×600 graphics window
    setbkcolor(RGB(128, 128, 128));      // Medium gray background
    cleardevice();                       // Clear the canvas
    srand((unsigned int)time(NULL));     // Initialize random number seed with time
    // Main loop framework
    while(true)  // Infinite loop for continuous interaction
    {
        // Create a 4×3 matrix of rotating snake patterns on the window
        for(int centerX = 100; centerX < 800; centerX += 200)
        {
            for(int centerY = 100; centerY < 600; centerY += 200)
            {
                // Initialize a single rotating snake unit
                float layerOffset = 0.0f;                    // Accumulated inter-layer angle offset
                // Random color generation system
                float hue = (float)(rand() % 180);           // Random hue (0-179°)
                COLORREF primaryColor = HSVtoRGB(hue, 0.9f, 0.8f);      // Primary hue
                COLORREF complementaryColor = HSVtoRGB(hue + 180.0f, 0.9f, 0.8f); // Complementary hue
                // Draw multi-layer concentric discs
                for(int radius = 100; radius > 0; radius -= 20)
                {
                    // Dynamically calculate bounding rectangle coordinates
                    int left   = centerX - radius;
                    int top    = centerY - radius;
                    int right  = centerX + radius;
                    int bottom = centerY + radius;
                    // Loop to draw sector units
                    for(int sectorIndex = 0; sectorIndex < 20; sectorIndex++)
                    {
                        // Angle calculation
                        float sectorOffset = sectorIndex * PI / 10.0f + layerOffset;
                        // Draw sector sequence (the key structure that creates the illusion)
                        // 1. Primary hue sector (replacing the original cyan area)
                        setfillcolor(primaryColor);
                        solidpie(left, top, right, bottom, sectorOffset, sectorOffset + 2*PI/60);
                        // 2. White high-contrast sector
                        setfillcolor(RGB(255, 255, 255));
                        solidpie(left, top, right, bottom,sectorOffset + 2*PI/60,sectorOffset + 3*PI/60);
                        // 3. Complementary hue sector (replacing the original red area)
                        setfillcolor(complementaryColor);
                        solidpie(left, top, right, bottom,sectorOffset + 3*PI/60,sectorOffset + 5*PI/60);
                        // 4. Black high-contrast sector
                        setfillcolor(RGB(0, 0, 0));
                        solidpie(left, top, right, bottom,sectorOffset + 5*PI/60,sectorOffset + 6*PI/60);
                    }
                    // Enhance inter-layer visual offset
                    layerOffset += PI / 20.0f;  // Increase offset by 9° for each layer
                }
            }
        }
        _getch();        // Wait for user input
        cleardevice();    // Clear screen to prepare for the next drawing
    }
    return 0;  // Program exits normally
}

Leave a Comment