C Exercise Example59
# C Programming Classic Example #59: Comprehensive Graphics Drawing
In legacy C programming, graphics rendering was a popular way to understand coordinate geometry, trigonometric functions, and hardware-level display modes. This tutorial demonstrates a comprehensive graphics program using the classic Turbo C `graphics.h` library.
We will analyze how to initialize a graphics environment, draw geometric shapes (circles and lines), apply trigonometric math to render rotating patterns, and handle user input to trigger visual transitions.
---
## 1. Problem Description
**Goal:** Create a comprehensive graphical drawing program that renders concentric circles, radial lines, text, and a dynamic rotating pattern using the legacy Turbo C graphics library.
### Program Analysis
1. **Graphics Initialization:** The program uses `initgraph()` to switch the display from text mode to graphics mode using the CGA driver (`CGA`) and CGA color palette 0 (`CGAC0`).
2. **Static Drawing:** It draws concentric circles using `circle()` and radial lines using trigonometric functions (`sin` and `cos`).
3. **Text and Fill Operations:** It displays a prompt using `outtextxy()` and fills a bounded region with a hatch pattern using `floodfill()`.
4. **Dynamic Animation:** It uses nested loops to continuously recalculate coordinates with an offset angle (`k`), creating a rotating or sweeping line effect.
---
## 2. Source Code Implementation
Below is the complete C program. The code has been updated with English comments and standard formatting.
```c
/**
* C Exercise Example 59 - Comprehensive Graphics Drawing
*
* Note: This program relies on the legacy "graphics.h" library,
* which is native to Turbo C/C++ environments.
*/
#define PAI 3.1415926 // Pi approximation
#define B 0.809 // Aspect ratio scaling factor for the Y-axis
#include "graphics.h"
#include "math.h"
#include "conio.h" // Required for getch()
int main()
{
int i, j, k, x0, y0, x, y, driver, mode;
float a;
// Set graphics driver to CGA and mode to CGAC0 (320x200 resolution)
driver = CGA;
mode = CGAC0;
initgraph(&driver, &mode, "");
// Set drawing color and background color
setcolor(3);
setbkcolor(GREEN);
// Define the center of the circles
x0 = 150;
y0 = 100;
// Draw three concentric circles
circle(x0, y0, 10);
circle(x0, y0, 20);
circle(x0, y0, 50);
// Draw 16 radial lines from the center
for (i = 0; i < 16; i++)
{
a = (2 * PAI / 16) * i;
x = ceil(x0 + 48 * cos(a));
y = ceil(y0 + 48 * sin(a) * B);
setcolor(2);
line(x0, y0, x, y);
}
// Draw an outer bounding circle
setcolor(3);
circle(x0, y0, 60);
/* Display prompt text using default font and size */
settextstyle(DEFAULT_FONT, HORIZ_DIR, 0);
outtextxy(10, 170, "Press a key...");
getch(); // Wait for user key press
// Fill a bounded region with a yellow hatch pattern
setfillstyle(HATCH_FILL, YELLOW);
floodfill(202, 100, WHITE);
getch(); // Wait for user key press again
// Animation loop: Redraw lines with a shifting phase angle
for (k = 0; k <= 500; k++)
{
setcolor(3);
for (i = 0; i <= 16; i++)
{
a = (2 * PAI / 16) * i + (2 * PAI / 180) * k;
x = ceil(x0 + 48 * cos(a));
y = ceil(y0 + 48 + sin(a) * B);
setcolor(2);
line(x0, y0, x, y);
}
for (j = 1; j <= 50; j++)
{
a = (2 * PAI / 16) * i + (2 * PAI / 180) * k - 1;
x = ceil(x0 + 48 * cos(a));
y = ceil(y0 + 48 * sin(a) * B);
line(x0, y0, x, y);
}
}
// Restore the screen to original text mode
restorecrtmode();
return 0;
}
```
---
## 3. Key Functions Explained
To understand how this program interacts with the screen, here is a breakdown of the key functions from `` used in this example:
| Function | Description |
| :--- | :--- |
| `initgraph(int *driver, int *mode, char *path)` | Initializes the graphics system by loading the graphics driver from disk and putting the system into graphics mode. |
| `circle(int x, int y, int radius)` | Draws a circle with its center at `(x, y)` and the specified `radius`. |
| `line(int x1, int y1, int x2, int y2)` | Draws a straight line between two points: `(x1, y1)` and `(x2, y2)`. |
| `settextstyle(int font, int direction, int size)` | Sets the current text font, direction (horizontal/vertical), and size character scale. |
| `outtextxy(int x, int y, char *text)` | Outputs a string of text at the specified coordinate `(x, y)`. |
| `setfillstyle(int pattern, int color)` | Sets the current fill pattern (e.g., solid, hatch, cross) and color for filling operations. |
| `floodfill(int x, int y, int border)` | Fills an enclosed area starting at seed point `(x, y)` up to the specified `border` color. |
| `restorecrtmode()` | Restores the screen to the mode it was in before graphics initialization (typically standard 80x25 text mode). |
---
## 4. Considerations & Modern Compatibility
### 1. Legacy Environment Requirement
The `` library and the `initgraph()` function are **not** part of the standard C library (ANSI C). They are proprietary to Borland Turbo C/C++ (MS-DOS era).
To run this code today, you have two primary options:
* **Option A (Recommended for Retro Coding):** Use **Turbo C++** inside an MS-DOS emulator like **DOSBox**.
* **Option B (Modern Port):** Use a modern port of the WinBGIm library (Windows Templates for Borland Graphics Interface) in IDEs like Code::Blocks or Dev-C++.
### 2. Aspect Ratio Correction
Notice the constant `#define B 0.809`. In older CRT monitors and CGA graphics modes, pixels were not perfectly square. Multiplying the Y-coordinate calculations by a scaling factor (like `0.809`) ensures that circular patterns do not look stretched or distorted on the screen.
YouTip