Things That Fall (More exp() Function Stuff)

Text mode graphics were a Big Deal with computers for the longest time. C’s stream I/O didn’t stop various computer games from being developed throughout the 1970s and 1980s. And this limitation isn’t going to stop me from animating a falling ball, er, asterisk.

In last week’s Lesson, I explored the exp() function, which is the mathematician’s equivalent of an ice cream sundae. While most of what it does or how it’s used is beyond me, the output is interesting enough that when applied graphically, it can be used to simulate how gravity affects a falling object.

The exponential function outputs results for a sequential series of numbers as small values that rapidly increase in size. This data can be used as the row value when positioning an object on the terminal (text) screen, which is how it makes the movement look natural. But before plotting, a few useful functions must be gathered to boost the C language’s lack of “fun” capabilities: clear(), putat(), and delay(). These functions are covered in previous Lessons, with the lot presented here.

The clear() function (macro) uses ANSI codes to clear the screen.

The putat() function uses ANSI codes to position the cursor and output a character.

The delay() function pauses program execution for a given number of milliseconds.

The setvbuf() function is also required. Its purpose is to remove line buffering for the standard output device. This modification allows the asterisks to be output without waiting for a newline or for the output buffer to fill.

Here is my code, which uses the exp() function’s output animate a falling asterisk:

2025_08_16-Lesson.c

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

#define clear() printf("\e[H\e[2J")

/* move the cursor to position x (columns)
   and y (rows) and set character c */
void putat(x,y,c)
{
    printf("\e[%d;%dH%c",y,x,c);
}

/* pause for m milliseconds */
void delay(int m)
{
    long pause;
    clock_t now,then;

    pause = m*(CLOCKS_PER_SEC/1000);
    now = then = clock();
    while( (now-then) < pause )
        now = clock();
}

int main()
{
    int x;
    double b;
    char buffer[BUFSIZ];

    /* initialization */
    setvbuf(stdout,buffer,_IONBF,BUFSIZ);
    clear();

    for( x=5; x<64; x++ )
    {
        b=exp( (double)x/20 );
        putat( 3, (int)b, '*' );
        delay(50);
        putat( 3, (int)b, ' ' );
    }
    putchar('\n');

    return 0;
}

Remember when building this code at the Linux command prompt to add the -lm (little L, little M) switch to link in the math library.

In the main() function, int variable x is the looping variable, ranging from 5 to 64. These values were used in last week’s Lesson as arguments for the exp() function — and they’re used here again. The results of exp( (double)x/20 ) range from 1.000000 through 23.336065. Each value generated is saved in double variable b.

Immediately, double variable b is typecast to an integer for use in the putat() function. The values, now ranging from 1 to 23, plot the asterisk’s location on the screen:

putat( 3, (int)b, '*' )

The program pauses for 50 milliseconds. Then the asterisk is “erased.” The loop repeats, plotting the asterisk’s position down the screen. Video of the output appears below:

Figure 1. Program output: the falling asterisk.
(Image repeats/cycles, but the program’s output does not.)

Remember that the for loop repeats 59 times. A lot of the initial action is the program overwriting the asterisk’s position with itself. Because the output from the exp() function changes little (especially when converted into an integer), the asterisk appears to hang for a while before dropping. This effect is what builds the animation.

In next week’s Lesson, I add code to bounce the asterisk across the terminal window.

4 thoughts on “Things That Fall (More exp() Function Stuff)

  1. This initial stage with the object falling straight down can be calculated using kinematics, the mathematics of an object moving in a straight line under constant acceleration (which can be 0). The 5 variables are suvat which I think is a fairly well known acronym:

    s: displacement (ie distance moved)
    u: initial velocity
    v: final velocity
    a: acceleration
    t: time

    In general you can calculate any of these if you know 2 or 3 others. For this problem you need to calculate s from u, a and t, repeating the calculation for each iteration. I put a bit of code together to calculate distances after 0 to 10 seconds but it should be easy to adapt it to use, for example, 0.05 seconds or 50 milliseconds.

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

    float uat_s(float u, float a, float t);

    int main()
    {
        float u = 0; // initial speed
        float a = 9.80665; // mean gravity on Earth
        float s;

        // loop for t = 0 to 10 seconds
        // (would need small fractions of second for animation)
        for(float t = 0; t<=10; t++)
        {
            s = uat_s(u, a, t); // calculate displacement
            printf(“%f %f\n”, t, s);
        }

        return 0;
    }

    // calculate displacement s from:
    // initial speed u
    // acceleration a
    // time t
    float uat_s(float u, float a, float t)
    {
        return u*t + 0.5*a*pow(t, 2);
    }

    This is the output:

    0.000000 0.000000
    1.000000 4.903325
    2.000000 19.613300
    3.000000 44.129925
    4.000000 78.453201
    5.000000 122.583130
    6.000000 176.519699
    7.000000 240.262924
    8.000000 313.812805
    9.000000 397.169342
    10.000000 490.332520

    It ignores air resistance so the actual distances would be less.

    Calculating the ball moving forward and bouncing like in the video in the previous article is a lot more complicated as it would involve working out the net of four forces, or actually I suppose three, gravity, air resistance and “bounciness” plus the forward momentum. Just plotting the trajectory would be a lot easier though as it’s just a series of parabolas.

  2. I forgot to mention that the variables are all SI Units, so distances are metres, velocities are metres per second, time is seconds and acceleration is metres per second per second. I should have given the output column headings. They’re seconds and distances.

    The values of s can easily be scaled to fit a terminal or window.

  3. I’m not a mathmatician, so only can contribute downspeed = a * t, downdistance = 1/2 a * t^2, don’t know if it’s beneficial to calculate with exp or “e”.

    And links to two nice videos:

    falling, games and binary floating-point (in)accuracy:
    https://www.youtube.com/watch?v=ei58gGM9Z8k
    watch and try to spot the fail in the analysis.

    SI system vs. “imperial” system of measurement:
    https://www.youtube.com/watch?v=r7x-RGfd0Yk
    watch and try not to laugh, try to find the advantage in “imperial”.

Leave a Reply