Draw a Circle in C — Midpoint Circle Algorithm (No graphics.h)

The classic way this exercise was taught — Turbo C’s <graphics.h> with initgraph() and circle(x, y, r) — hasn’t compiled on a mainstream system in decades: graphics.h was a Borland DOS library, not part of C. But the underlying question is still excellent: how does a computer decide which pixels form a circle? The answer is the midpoint circle algorithm (Bresenham’s circle), which draws a perfect circle using only integer arithmetic — no floating point, no sqrt(), no trigonometry. This page implements it in portable C that renders the circle as ASCII output in any terminal, tested and warning-free.

How the Midpoint Circle Algorithm Works — Step by Step

  1. Exploit symmetry: a circle is 8-way symmetric. Compute just one octant (from the top, 45° down) and mirror every point into the other seven octants for free.
  2. Start at the top: (x, y) = (0, r), with a decision variable d = 1 − r.
  3. At each step, move east or southeast: the decision variable tracks whether the midpoint between the two candidate pixels lies inside or outside the ideal circle. Inside (d < 0): keep y, update d += 2x + 3. Outside: decrement y, update d += 2(x − y) + 5.
  4. Stop when x > y — the octant is complete, and symmetry has already painted the rest.

The entire circle costs ~r/√2 iterations of integer adds and shifts — this is why every graphics library from DOS BGI to modern GPUs rasterizes circles this way.

C Program to Draw a Circle (Midpoint Algorithm, ASCII Output)

#include <stdio.h>
#include <string.h>

#define SIZE 41                   /* odd, so the centre is a single cell */

static char grid[SIZE][SIZE];

static void plot(int cx, int cy, int x, int y)
{
    /* plot all 8 symmetric octant points, if inside the grid */
    int px[8], py[8], i;

    px[0] = cx + x; py[0] = cy + y;
    px[1] = cx - x; py[1] = cy + y;
    px[2] = cx + x; py[2] = cy - y;
    px[3] = cx - x; py[3] = cy - y;
    px[4] = cx + y; py[4] = cy + x;
    px[5] = cx - y; py[5] = cy + x;
    px[6] = cx + y; py[6] = cy - x;
    px[7] = cx - y; py[7] = cy - x;

    for (i = 0; i < 8; i++) {
        if (px[i] >= 0 && px[i] < SIZE && py[i] >= 0 && py[i] < SIZE) {
            grid[py[i]][px[i]] = '*';
        }
    }
}

int main(void)
{
    int r, cx, cy, x, y, d, row, col;

    printf("Enter the radius (1-%d): ", (SIZE - 1) / 2);
    if (scanf("%d", &r) != 1 || r < 1 || r > (SIZE - 1) / 2) {
        printf("Invalid radius.\n");
        return 1;
    }

    memset(grid, ' ', sizeof grid);
    cx = SIZE / 2;
    cy = SIZE / 2;

    /* midpoint circle algorithm: start at the top, walk one octant */
    x = 0;
    y = r;
    d = 1 - r;                    /* decision variable */
    while (x <= y) {
        plot(cx, cy, x, y);
        if (d < 0) {
            d = d + 2 * x + 3;            /* midpoint inside: go east      */
        } else {
            d = d + 2 * (x - y) + 5;      /* midpoint outside: go southeast */
            y--;
        }
        x++;
    }

    /* print only the rows the circle touches; double the columns so the
       output looks round in a terminal (characters are taller than wide) */
    for (row = cy - r; row <= cy + r; row++) {
        for (col = cx - r; col <= cx + r; col++) {
            printf("%c ", grid[row][col]);
        }
        printf("\n");
    }
    return 0;
}

How to Compile and Run

gcc -ansi -Wall -Wextra -o circle circle.c
./circle

Sample Output

Radius 10:

Enter the radius (1-20): 10
              * * * * * * *
          * *               * *
        *                       *
      *                           *
    *                               *
  *                                   *
  *                                   *
*                                       *
*                                       *
*                                       *
*                                       *
*                                       *
*                                       *
*                                       *
  *                                   *
  *                                   *
    *                               *
      *                           *
        *                       *
          * *               * *
              * * * * * * *

Radius 3 produces a tidy 7-row circle — try several radii and watch the stepping pattern change.

Code Explanation

  • plot() — one computed point becomes eight drawn points via the symmetry mirrors. This is the whole reason the algorithm only walks 45° of arc.
  • d = 1 - r and the +3 / +5 updates — integer-only bookkeeping for “is the true circle inside or outside the midpoint between my two candidate pixels?” No sqrt, no sin/cos, no rounding errors.
  • printf("%c ", ...) — the extra space doubles each column because terminal characters are roughly twice as tall as wide; without it the circle prints as an egg.
  • memset(grid, ' ', sizeof grid) — a 2-D char canvas is the terminal’s frame buffer; separating “compute the pixels” from “render the canvas” is exactly how real rasterizers are structured.

What About graphics.h?

Honest status: <graphics.h> is the Borland Graphics Interface from Turbo C (1987–1994, MS-DOS). It is not part of any C standard and won’t compile with modern GCC, Clang, or MSVC. If a course still requires it, the practical route is the WinBGIm port bundled with some Windows IDEs — but for real graphics in C today, learn SDL2 or raylib instead; both are free, cross-platform, and actively maintained. The midpoint algorithm above is the same math you’d use to plot pixels in either.

Time and Space Complexity

Aspect Complexity Why
Time O(r) ~r/√2 loop iterations, 8 plots each
Space O(SIZE²) the character canvas
Arithmetic integer only adds and comparisons — no floating point at all

What This Program Teaches

  • The midpoint/Bresenham technique: replacing geometry with an incremental integer decision variable
  • 8-way symmetry — compute once, mirror everywhere
  • Separating computation (plot into a buffer) from presentation (render the buffer)
  • The real story of graphics.h, and what to use instead in 2026

Related C Programs

Test yourself: our free C Programming Quiz app for Android has 150+ questions with explanations for every answer.

Recommended Book

The C Programming Language by Kernighan & Ritchie remains the definitive C reference — we’ve solved all of its exercises. Also on Amazon.com.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>