Graphing Curves in Text Mode

When it comes to plotting curves in the C language, you need to dust off your trigonometry. It’s not a scary thing: The C library offers a host of mathematical functions, many of which can help you plot a curve here or there. In fact, writing a function to draw a curve is a lot easier than plotting a straight line.

As an example, consider a sine wave, such as the one shown in Figure 1.

Figure 1. A sine wave, plotting y=sin(x).

Figure 1. A sine wave, plotting y=sin(x).

The sine wave is a basic curve, something people recognize, although not everyone may know that it’s called a sine wave.

In Figure 1, you see a plot of the function y=sin(x). Because sin() is also a C library function (declared in the math.h header), you can whip up a tiny little program that spews out all the coordinates necessary to plot that curve:

#include <stdio.h>
#include <math.h>

int main()
{
    float x,y;

    for(x=-3.14159;x<=3.14159;x+=1.0)
    {
        y = sin(x);
        printf("%.2f\t%.2f\n",x,y);
    }

    return(0);
}

The for loop at Line 8 steps through x values from negative π through positive π.

The value of y is calculated as the sine of x at Line 10.

In Line 11, the x and y “coordinates” are output, the coordinates you could use to plot the curve.

Here’s the sample output:

-3.14	-0.00
-2.14	-0.84
-1.14	-0.91
-0.14	-0.14
0.86	0.76
1.86	0.96
2.86	0.28

Obviously the line wouldn’t be very detailed given those coordinates; seven points doesn’t make a very pretty curve.

The solution is to increase the stepping value in the for loop. Modify Line 8 to read:

for(x=-3.14159;x<=3.14159;x+=0.1)

The results are far more detailed when the stepping value is 0.1 instead of 1.0.

To plot the curve using text mode graphics, you need to do two additional things.

First, you need to increase the wave’s amplitude and wave length. The current numbers are accurate, but they won’t graph well in text mode. So you need to make the wave proportionally larger.

Second, you need to convert the wave’s coordinates from floating point to integer; the plot() function accepts int values. For that conversion, I’ll use the rintf() function.

The rintf() function is a rounding function. It takes a floating point value and rounds it up or down to the nearest integer. rintf() requires the math.h header file.

Below you see the code I’ve concocted to plot and display a sine wave. This code uses the basic graphic functions from earlier Lessons, but it omits the line-plotting functions.

#include <stdio.h>
#include <math.h>

#define WIDTH 60
#define HEIGHT 20
#define X WIDTH/2
#define Y HEIGHT/2
#define XMAX WIDTH-X-1
#define XMIN -(WIDTH-X)
#define YMAX HEIGHT-Y
#define YMIN -(HEIGHT-Y)+1

char grid[HEIGHT][WIDTH];

int plot(int x, int y);
void init_grid(void);
void show_grid(void);

int main()
{
    float x,y;

    init_grid();
    for(x=-3.14159;x<=3.14159;x+=0.1)
    {
        y = sin(x);
        plot(rintf(x*10),rintf(y*8));
    }
    show_grid();

    return(0);
}

/* Set "pixel" at specific coordinates */
int plot(int x, int y)
{
    if( x > XMAX || x < XMIN || y > YMAX || y < YMIN )
        return(-1);

    grid[Y-y][X+x] = '*';
    return(1);
}

/* Initialize grid */
void init_grid(void)
{
    int x,y;

    for(y=0;y<HEIGHT;y++)
        for(x=0;x<WIDTH;x++)
            grid[y][x] = ' ';
    /* draw the axis */
    for(y=0;y<HEIGHT;y++)
        grid[y][X] = '|';
    for(x=0;x<WIDTH;x++)
        grid[Y][x] = '-';
    grid[Y][X] = '+';
}

/* display grid */
void show_grid(void)
{
    int x,y;

    for(y=0;y<HEIGHT;y++)
    {
        for(x=0;x<WIDTH;x++)
            putchar(grid[y][x]);
        putchar('\n');
    }
}

The key to drawing the curve is the plot() function. The code between Lines 24 through 28 calculates the points by using the for loop example shown earlier in this Lesson.

Figure 2 shows the output.

Figure 2. A sine wave drawn by using text mode graphics.

Figure 2. A sine wave drawn by using text mode graphics.

Pretty!

You could replace the sin() function in Line 26 with the cos() function to behold a cosine wave. And if you’re too lazy for that, just look at Figure 3.

Figure 3. The plot of a cosine wave.

Figure 3. The plot of a cosine wave.

Of course, these curves are easy because the C library is doing the math. What’s a wee bit more difficult to plot is a circle. That code is presented in next week’s Lesson.