
One good way of making an animation is by simulating a physical system and illustrating the variables in that system using a dynamically changing graphical display.

The classic such physical system is a simple gravity pendulum.



Task

Create a simple physical model of a pendulum and animate it.




'declare and initialize variables
CONST PI = 3.141592
 
DIM SHARED Bob_X, Bob_Y, Pivot_X, Pivot_Y, Rod_Length, Rod_Angle, Bob_Angular_Acceleration, Bob_Angular_Velocity, Delta_Time, Drawing_Scale, G AS DOUBLE
DIM SHARED exit_flag AS INTEGER
 
'set gravity to Earth's by default (in m/s squared)
G = -9.80665
 
'set the pivot at the screen center near the top. Positions are in meters not pixels, and they translate to 320 and 60 pixels
Pivot_X = 1.6
Pivot_Y = 0.3
 
'set the rod length, 0.994 meters by default (gives 1 second period in Earth gravity)
Rod_Length = 0.994
'set the initial rod angle to 6 degrees and convert to radians. 6 degrees seems small but it is near to what clocks use so it
'makes the pendulum look like a clock's. More amplitude works perfectly but looks silly.
Rod_Angle = 6 * (PI / 180)
'set delta time, seconds. 5 miliseconds is precise enough.
Delta_Time = 0.05
 
'because the positions are calculated in meters, the pendulum as drawn would be way too small (1 meter = 1 pixel),
'so a scale factor is introduced (1 meter = 200 pixels by default)
Drawing_Scale = 200
 
'initialize the screen to 640 x 480, 16 colors
SCREEN 12
 
'main loop
DO
    'math to figure out what the pendulum is doing based on the initial conditions.
 
    'first calculate the position of the bob's center based on the rod angle by using the sine and cosine functions for x and y coordinates
    Bob_X = (Pivot_X + SIN(Rod_Angle) * Rod_Length)
    Bob_Y = (Pivot_Y + COS(Rod_Angle) * Rod_Length)
    'then based on the rod's last angle, length, and gravitational acceleration, calculate the angular acceleration
    Bob_Angular_Acceleration = G / Rod_Length * SIN(Rod_Angle)
    'integrate the angular acceleration over time to obtain angular velocity
    Bob_Angular_Velocity = Bob_Angular_Velocity + (Bob_Angular_Acceleration * Delta_Time)
    'integrate the angular velocity over time to obtain a new angle for the rod
    Rod_Angle = Rod_Angle + (Bob_Angular_Velocity * Delta_Time)
 
    'draw the user interface and pendulum position
 
    'clear the screen before drawing the next frame of the animation
    CLS
 
    'print information
    PRINT "   Gravity: " + STR$(ABS(G)) + " m/sý, Rod Length: " + STR$(Rod_Length); " m"
    LOCATE 25, 1
    PRINT "+/- keys control rod length, numbers 1-5 select gravity, (1 Earth, 2 the Moon, 3 Mars, 4 more 5 less), Q to exit"
 
    'draw the pivot
    CIRCLE (Pivot_X * Drawing_Scale, Pivot_Y * Drawing_Scale), 5, 8
    PAINT STEP(0, 0), 8, 8
 
    'draw the bob
    CIRCLE (Bob_X * Drawing_Scale, Bob_Y * Drawing_Scale), 20, 14
    PAINT STEP(0, 0), 14, 14
 
    'draw the rod
    LINE (Pivot_X * Drawing_Scale, Pivot_Y * Drawing_Scale)-(Bob_X * Drawing_Scale, Bob_Y * Drawing_Scale), 14
 
    'process input
    SELECT CASE UCASE$(INKEY$)
        CASE "+"
            'lengthen rod
            Rod_Length = Rod_Length + 0.01
        CASE "-"
            'shorten rod
            Rod_Length = Rod_Length - 0.01
        CASE "1"
            'Earth G
            G = -9.80665
        CASE "2"
            'Moon G
            G = -1.62
        CASE "3"
            'Mars G
            G = -3.721
        CASE "4"
            'More G
            G = G + 0.1
        CASE "5"
            'Less G
            G = G - 0.1
        CASE "Q"
            'exit on any other key
            exit_flag = 1
    END SELECT
 
    'wait before drawing the next frame
    _DELAY Delta_Time
 
    'loop the animation until the user presses any key
LOOP UNTIL exit_flag = 1