YouTip LogoYouTip

C Exercise Example65

# C Programming Exercise Example 65: Drawing an Elegant Geometric Pattern In legacy C programming, particularly within MS-DOS environments like Turbo C (TC), developers used the Borland Graphics Interface (`graphics.h`) to create rich visual displays. This tutorial demonstrates how to draw a highly symmetrical, elegant geometric pattern (a complete graph or "mystic rose") by connecting evenly spaced points along the circumference of a circle. --- ## 1. Introduction The goal of this exercise is to generate an intricate geometric pattern using basic trigonometric functions and line-drawing routines. The program calculates $N$ equidistant points along the perimeter of a circle. It then draws a line (chord) from every point to every other point. This mathematical structure is known in graph theory as a **Complete Graph ($K_n$)**. When rendered, it forms a beautiful, rosette-like geometric pattern. --- ## 2. Mathematical and Logical Analysis To construct this pattern, we perform the following steps: 1. **Determine the Center and Radius**: Find the center of the active viewport and calculate a suitable radius based on the screen's aspect ratio. 2. **Calculate Circumference Points**: Divide the $360^\circ$ circle into $N$ equal angular increments (where $N = 15$ in this example). 3. **Convert to Radians**: Since standard C math library functions (`sin`, `cos`) expect angles in radians, convert degrees using the formula: $$\text{radians} = \text{angle} \times \frac{\pi}{180}$$ 4. **Map Coordinates**: Calculate the $(x, y)$ coordinates for each of the $15$ points: $$x = x_{\text{center}} + \cos(\theta) \times \text{radius}$$ $$y = y_{\text{center}} - \sin(\theta) \times \text{radius} \times \text{AspectRatio}$$ 5. **Connect All Points**: Use a nested loop to draw a line from each point $i$ to every subsequent point $j$ (where $j \ge i$). --- ## 3. Source Code Implementation Below is the complete C program. This code is designed for compilers that support the legacy Turbo C graphics library (`graphics.h`). ```c /* Created by www.runoob.com on 15/11/9. Copyright Β© 2015 Runoob. All rights reserved. English translation and annotations for YouTip. */ #include "graphics.h" #include "math.h" #include "dos.h" #include "conio.h" #include "stdlib.h" #include "stdio.h" #include "stdarg.h" #define MAXPTS 15 #define PI 3.1415926 struct PTS { int x, y; }; double AspectRatio = 0.85; void LineToDemo(void) { struct viewporttype vp; struct PTS points; int i, j, h, w, xcenter, ycenter; int radius, angle, step; double rads; printf(" MoveTo / LineTo Demonstration" ); /* Retrieve current viewport settings to determine screen dimensions */ getviewsettings(&vp); h = vp.bottom - vp.top; w = vp.right - vp.left; /* Determine the center of the circle */ xcenter = w / 2; ycenter = h / 2; /* Calculate the radius adjusted for aspect ratio */ radius = (h - 30) / (AspectRatio * 2); /* Determine the angular step size for 15 points */ step = 360 / MAXPTS; angle = 0; /* Start at 0 degrees */ /* Calculate and store the coordinates of the 15 points */ for (i = 0; i < MAXPTS; ++i) { rads = (double)angle * PI / 180.0; /* Convert angle to radians */ points.x = xcenter + (int)(cos(rads) * radius); points.y = ycenter - (int)(sin(rads) * radius * AspectRatio); angle += step; /* Move to the next point */ } /* Draw the outer bounding circle */ circle(xcenter, ycenter, radius); /* Draw the chords connecting every point to every other point */ for (i = 0; i < MAXPTS; ++i) { for (j = i; j < MAXPTS; ++j) { /* Connect to all subsequent points */ moveto(points.x, points.y); /* Move pen to starting point */ lineto(points.x, points.y); /* Draw line to target point */ } } } int main() { int driver, mode; /* Initialize graphics system using CGA mode */ driver = CGA; mode = CGAC0; initgraph(&driver, &mode, ""); /* Set drawing color and background color */ setcolor(3); setbkcolor(GREEN); /* Run the geometric pattern demonstration */ LineToDemo(); /* Wait for user input before closing the graphics window */ getch(); closegraph(); return 0; } ``` --- ## 4. Code Explanation * **`struct PTS`**: A simple structure used to store the $(x, y)$ coordinate pairs of the points on the circle. * **`getviewsettings()`**: A Borland Graphics Interface (BGI) function that retrieves the boundaries of the current viewport, allowing the program to dynamically center the drawing regardless of screen resolution. * **`moveto(x, y)` and `lineto(x, y)`**: * `moveto` shifts the virtual drawing cursor to the specified coordinates without drawing. * `lineto` draws a line from the current cursor position to the new coordinates. * **Nested Loops**: The outer loop selects a starting point $i$, and the inner loop iterates through all points $j \ge i$. This ensures that every unique pair of points is connected by exactly one line, preventing redundant drawing operations. --- ## 5. Compilation and Compatibility Considerations Because this program relies on the legacy `` library, compiling it on modern operating systems requires specific configurations: 1. **Using Turbo C++ / DOSBox**: * The easiest way to run this code unmodified is inside a pre-configured DOSBox environment running Turbo C++ 3.0. * Ensure that the linker is set to include the Graphics Library (`Options > Linker > Libraries > Graphics library` set to **ON**). * Make sure the path to the BGI directory (usually `C:\TC\BGI`) is correctly configured in your environment. 2. **Using Modern Compilers (GCC / Clang)**: * Standard modern compilers do not support `graphics.h` natively. * To run this on modern Windows, macOS, or Linux, you can use alternative libraries such as **WinBGIm** (a C++ graphics library emulation for GCC) or modern multimedia libraries like **SDL2** or **SFML** to recreate the drawing logic.
← C Exercise Example66C Exercise Example64 β†’