96 lines
3.4 KiB
Text
96 lines
3.4 KiB
Text
'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
|