Universe is a two-body gravitational simulation that models the motion of two masses under mutual gravitational attraction. The user inputs mass, initial velocity, launch angle, and starting coordinates for each body, along with the gravitational constant, giving full control over the simulated physics. Velocities are decomposed into x and y components using trigonometry, and each time step applies Newtonian kinematics: displacement is calculated as s = v·dt + ½a·dt², then velocities are updated with v = v + a·dt. The simulation runs in a continuous loop, plotting each body’s incremental displacement with PLOT/DRAW to trace orbital paths on screen, with dt fixed at 0.1 time units per step.
Program Structure
The program is organized into three logical phases separated by REM statements:
- Input and initialization (lines 30–110): Collects parameters for both bodies, converts angles to radians, offsets x-coordinates by 10, draws initial circles, and decomposes velocities into x/y components.
- Physics processing (lines 120–230): Computes gravitational force, resolves it into components, calculates accelerations, then updates displacements and velocities for both bodies.
- Plotting and position update (lines 240–280): Draws each body’s step displacement on screen, updates coordinates, and loops back to line 120 unconditionally.
Physics Implementation
The simulation uses a fixed time step of dt = 0.1 (line 80). Newton’s law of gravitation is applied at line 130:
fg = g * m1 * m2 / ((x2-x1)² + (y2-y1)²)
This correctly computes the scalar gravitational force magnitude. The angle phi of the line joining the two bodies is found via ATN at line 150, with a special case at line 140 to avoid division by zero when the bodies share the same x-coordinate. Force components are then computed using COS phi and SIN phi, with SGN used to correctly assign direction based on relative position. Each body’s acceleration, displacement, and velocity are updated independently for x and y axes (lines 180–230) using the kinematic equation s = v·dt + ½·a·dt².
Notable Techniques
- Angle inputs are entered in degrees and converted to radians with
* PI/180at line 80, a common idiom. SGN (x2-x1)andSGN (y2-y1)at lines 160–170 elegantly handle the four quadrant cases for force direction without branching.- The x-coordinates are shifted by +10 at line 80 (
x1=x1+10,x2=x2+10), presumably to move bodies away from the left edge of the display area. - PLOT/DRAW is used to trace orbital paths:
PLOT x1,y1: DRAW s1x,s1ydraws a line from the current position by the incremental displacement, effectively painting the trajectory incrementally. - Initial body positions are marked with
CIRCLE x1,y1,2at line 90, providing a visual reference for starting locations.
Bugs and Anomalies
- Singularity on collision: Line 130 divides by the squared distance between the bodies. If the two bodies occupy the same position, this produces a division-by-zero error. There is no collision detection or minimum-distance guard.
- Force magnitude formula: The denominator at line 130 uses the squared distance, which is correct for the force magnitude. However, the angle
phiis derived fromATN ABS(...)and then signed viaSGN. BecauseATNonly returns values in (−π/2, π/2), taking the absolute value of the argument and reapplying sign viaSGNis a valid workaround, but only works correctly because the force direction is reconstructed separately viaSGN— the approach is correct but unconventional. - Screen boundary: No bounds checking is performed on x or y coordinates. Bodies that drift off-screen will cause a PLOT/DRAW error.
- Euler integration drift: The integrator is first-order Euler for velocities (line 200/230) combined with a displacement formula that includes a second-order correction term. This mixed scheme is not fully second-order accurate (a proper Leapfrog or Verlet integrator would be more energy-conserving), so orbits will gradually drift over long runs.
- Variable name conflict: Input angles are stored as
a1anda2, which are then overwritten with radian-converted values at line 80. Later,a1x,a1y,a2x,a2yare used for accelerations (lines 180, 210). This is not a bug, but the reuse ofa1/a2for angle then implicitly dropped could confuse readers.
Key Variables
| Variable | Description |
|---|---|
m1, m2 | Masses of the two bodies |
v1, v2 | Initial speed magnitudes |
a1, a2 | Launch angles (degrees, converted to radians in-place) |
x1, y1, x2, y2 | Current body coordinates |
g | User-supplied gravitational constant |
dt | Fixed time step (0.1) |
fg | Scalar gravitational force between bodies |
phi | Angle of the vector joining the two bodies |
v1x, v1y, v2x, v2y | Velocity components |
s1x, s1y, s2x, s2y | Displacement increments per time step |
Source Code
10 REM model universe
20 REM @W.R.MAZEFIELD 1983
30 REM INPUT DATA
40 BORDER 0:INK 7:PAPER 0:CLS
50 CLS :PRINT "MODEL UNIVERSE":PRINT
60 INPUT " First Body:"'"Mass? ";m1'"Velocity? ";v1'"Angle? ";a1'"x coord? ";x1,"y coord ";y1,'" Second Body:"'"Mass? ";m2'"Velocity? ";v2'"Angle? ";a2'"x coord? ";x2,"y coord? ";y2'"Gravitational Constant? ";g:CLS
70 PRINT TAB 23;"M1=";m1' TAB 23;"v1=";v1' TAB 23;"A1=";a1' TAB 23;"x1=";x1' TAB 23;"y1=";y1' TAB 23;"M2=";m2' TAB 23;"v2=";v2' TAB 23;"A2=";a2' TAB 23;"x2=";x2' TAB 23;"y2=";y2' TAB 23;" G=";g
80 LET dt=0.1:LET a1=a1* PI/180:LET a2=a2* PI/180:LET x1=x1+10:LET x2=x2+10
90 CIRCLE x1,y1,2:CIRCLE x2,y2,2
100 LET v1x=v1* COS a1:LET v2x=v2* COS a2
110 LET v1y=v1* SIN a1:LET v2y=v2* SIN a2
120 REM Processing
130 LET fg=g*m1*m2/((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
140 IF x2=x1 THEN LET phi= PI/2:GO TO 160
150 LET phi= ATN ABS ((y2-y1)/(x2-x1))
160 LET f1x=fg* COS phi* SGN (x2-x1):LET f2x=-f1x
170 LET f1y=fg* SIN phi* SGN (y2-y1):LET f2y=-f1y
180 LET a1x=f1x/m1:LET a2x=f2x/m2
190 LET s1x=v1x*dt+a1x*dt*dt/2:LET s2x=v2x*dt+a2x*dt*dt/2
200 LET v1x=v1x+a1x*dt:LET v2x=v2x+a2x*dt
210 LET a1y=f1y/m1:LET a2y=f2y/m2
220 LET s1y=v1y*dt+a1y*dt*dt/2:LET s2y=v2y*dt+a2y*dt*dt/2
230 LET v1y=v1y+a1y*dt:LET v2y=v2y+a2y*dt
240 REM PLOT
250 PLOT x1,y1:DRAW s1x,s1y:PLOT x2,y2:DRAW s2x,s2y
260 LET x1=x1+s1x:LET x2=x2+s2x
270 LET y1=y1+s1y:LET y2=y2+s2y
280 GO TO 120
290 SAVE "Universe" LINE 30:BEEP .4,15Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
