
This model of the Solar System shows all the planets (including the Moon and Pluto) orbiting around the Sun. You can adjust the display speed and the zoom to show the inner and outer planets moving at their correct relative speeds.
You can have the program stop at a particular date by choosing "Enter a starting date", or you can toggle Stop/Go by tapping a button. One check for accuracy is to enter a stop date for a future eclipse or conjunction etc, then note the position of the moon or planet on the display. (Sorry; 31 Jan 2025 is the earliest date it will accept).
Although this program shows the planets positions reasonably accurately on any particular date, it is not designed to be precise; the orbit diameters are to scale, but are circular, not elliptical, so the orbital speeds are constant, not varying at perihelion and aphelion. This will give a slight inaccuracy in their positions, which, at the scale drawn, will probably not be noticeable to the naked eye. In particular, Pluto's orbit is represented by a circle with its centre offset from the Sun so that it crosses Neptune's orbit in a realistic looking manner, though not perfectly accurate.
The Moons distance from earth is greatly exaggerated to make it distinguishable from Earth.
The planets sizes are not to scale, other than the inner planets being smaller than the outer ones. The sizes do not change with the scale.
Day#1 is Jan 31/2025, because that was the best date I could find starting data for.
Note: Celestial Longitude is measured CCW; Smart BASIC measures angles CW.
Undoubtedly, there will be routines that could be simpler than what I have done.
Code: Select all
g'
/*
This program is an "Orrery". Look it up. 😊
Version 2: misc improvements: Pause, improved scaling, 2-digit year input
Although this program shows the planets positions reasonably accurately on any particlar date, it is not designed to be precise; the orbit diameters are to scale, but are circular, not elliptical, so the orbital speeds are constant, not varying at perihelion & aphelion. This will give a slight inaccuracy in their positions, which, at the scale drawn, will probably not be noticeable to the naked eye. In particular, Pluto's orbit is represented by a circle with its centre offset from the Sun so that it crosses Neptunes orbit in a realistic looking manner, though not perfectly accurate.
The Moons distance from earth is greatly exaggerated to make it distinguishable from Earth.
The planets sizes are not to scale, other than the inner planets being smaller than the outer ones. The sizes do not change with the scale.
Day#1 is Jan 31/2025, because that was the best date I could find starting data for.
Note: Celestial Longitude is measured CCW; Smart BASIC measures angles CW.
===========================================================
RAW DATA from an astronomy handbook; only used for ref when writing program:
Dist(millions-km) Revolution(days)
Mercury 57.9 88.0
Venus 108.1 224.7
Earth 149.5 365.258
Mars 227.8 687.0
Jupiter 778 4332 days = 11.86 years (program works in days)
Saturn 1427 10760 = 29.46
Uranus 2869 30685 = 84.01
Neptune 4497 60195 = 164.8
Pluto 5900 90475 = 247.7
Moon 0.3 27.321661
Pluto Eccentricity = 0.25 Longitude of Perihelion = 224º
Pluto's eccentricity is simulated by an offset circle.
Pluto Long of Perihelion = 224º
*/ '=============== PROGRAM BEGINS HERE =============================
'b'
OPTION BASE 1
OPTION ANGLE DEGREES
SET BUTTONS CUSTOM
DIM pname$(10), dist(10), pper(10), ppos(10), mon$(13), days(13) 'dacc(13)
' pperiod (days), dist (mill km) init pos of planets is 31 Jan/25.
'r'
'Calendar for dates:
DATA "Jan",31,"Feb",28,"Mar",31,"Apr",30,"May",31,"Jun",30,"Jul",31,"Aug",31
DATA "Sep",30, "Oct",31,"Nov",30, "Dec",31
FOR i=1 TO 12
READ mon$(i), days(i)
NEXT i
'------------------------------------
'Table of planet data:
' Dist(mill km) RevPer'd(d) Start date is initial pang() of Jan 31/2025
DATA "Mercury", 57.9, 88.0, -289, "Venus", 108.1, 224.7, -100, "Earth", 149.5, 365.258, -131
DATA "Mars", 227.8, 687.0, -123, "Jupiter", 778, 4331.98, -81, "Saturn", 1427, 10760, -350
DATA "Uranus", 2869, 30685, -56, "Neptune", 4497, 60194, 1, "Pluto",5900,90475, 60, "Moon", 7, 27.321661, 25 'moon dist is exaggerated to display outside earth.
' Note: Plutos orbit is centred at OFFSET of 56, -73 to simulate ellipse.
FOR i=1 TO 10 'incl moon when i=10
READ pname$(i), dist(i), pper(i), pang(i)
'1st pang(i) (starting date) is init pos of planets on JAN 31/25.
' Note: initial pang() (planet angle) is stang() (starting angle)====
ovel(i)= -360/pper(i) 'orbital vel.(degrees/day) (**is ccw) ==============
NEXT i
' STARTUP DATE =================================================
yr=2025 'starting date (day #1); replaces stdate(), stmon() etc above
m=1 ' Start date is Jan 31/2025
d=31 ! day=0 ' 1 is added to date & day# on 1st iteration of "main:" loop.
STEP=1 'default
'c'
sw=SCREEN_WIDTH() ! sh=SCREEN_HEIGHT() ' 1024 x 724
sw2=sw/2-50 ! sh2=sh/2 ' 50 left of centre screen, to allow plutos orbit
dscale= .8 ' scale for drawing circles (orbits)
50
TEXT CLEAR
PRINT "Do you want to enter Stop date? y/n" ' if you want to stop at given date
INPUT y$ ! y$=LOWSTR$(y$)
IF y$<>"y" AND y$<>"n" THEN GOTO 50
55
IF y$="y" THEN
TEXT CLEAR
PRINT "*NOTE: STOP DATE MUST BE AFTER 31 JAN, 2025! *"
PRINT "Enter date (day): "; ! INPUT dsp ! PRINT dsp ' stop date
PRINT "Enter month #: "; ! INPUT msp ! PRINT mon$(msp)
PRINT "Enter year (yy or yyyy): "; ! INPUT ysp
IF ysp<100 THEN ysp=ysp+2000 ! PRINT ysp ! PAUSE 2 ' allows 2-digit year for 2000's
IF dsp>31 OR msp>12 OR ysp<2025 THEN GOTO 55 ' partial error check
'y$="n"
ENDIF
''
GRAPHICS
FILL COLOR 1,0,0 ' for button colour
BUTTON "toggle" TEXT "PAUSE" AT sw-200, sh-80 SIZE 130,70
SLIDER "scale" VALUE 0.2 AT 1000, 600 SIZE 400 ANGLE -90 ' for dscale
SLIDER "speed" VALUE 0.1 AT 20, 600 SIZE 400 ANGLE -90
y$="n"
dsc=0 'initial scale
'g'================= MAIN LOOP ============================
main:
REFRESH OFF ' stops flicker - don't update screen during calculations,
GRAPHICS CLEAR 0, 0, .3 'very dark blue
'Heliocentric Longitude markers ---------------------
DRAW LINE sw2+250,sh2 TO sw2+330, sh2 ! DRAW TEXT "0º" AT sw2+335,sh2-10
DRAW LINE sw2-250,sh2 TO sw2-330, sh2 ! DRAW TEXT "180º" AT sw2-380,sh2-10
DRAW LINE sw2,sh2-250 TO sw2, sh2-300 ! DRAW TEXT "90º" AT sw2-13,sh2-320
DRAW LINE sw2,sh2+250 TO sw2, sh2+315 ! DRAW TEXT "270º" AT sw2-18,sh2+320
sv2=SLIDER_VALUE("speed") 'orbital speed
IF sv2<=0.2 THEN ' The lower part controls the PAUSE duration (at the
STEP=1 ' end of the loop), allowing a slower
pdelay=24*(sv2-.2)^2 ' display speed for the inner planets.
ENDIF
IF sv2>.3 THEN 'The upper part of the slider range varies the STEP, ie
'how many days pass for each iteration of the loop,
'allowing a higher display speed for the outer planets.
' *NOTE: if STEP> ~15 or 20 the accuracy will be reduced.*
DRAW COLOR 1, .5, .5
DRAW TEXT "*STEP IS " & INT(STEP) & " DAYS" AT 40,450 'WARNING msg:
' if STEP >than ~20 days, accuracy may be reduced.
DRAW COLOR 1,1,1
pdelay=0 ' pause at end of main: loop
STEP=INT(MAX(1,200*(sv2-.3)^2))
ENDIF
dstp=dsp-d
IF y$="y" AND yr=ysp AND m=msp-1 THEN STEP=1 ' slow down before stopping,
' so not to miss stop date.
'DRAW TEXT sv2 AT 40,400 'if you want to display it
DRAW LINE 1, 510 TO 50,510 'just a marker for change of STEP.
'r'-----------------------------------
' DATE CALCULATION: =========--=-=-=-=-=-=-=-=-=-=
IF g=1 THEN GOTO 100 ' paused - don't increment date or planet positions
d2=day
day=day+STEP ' day# from start
400
d=d+1 ' day of month
days(2)=28 ' reset to default after leap year
IF m=2 AND yr1=INTEG(yr1) AND yr1/100<>INTEG(yr1/100) THEN days(2)=29 'is leap year
IF d>days(m) THEN ' next month
m=m+1
IF m>12 THEN ' next year
m=1 ' reset month to Jan
yr=yr+1 ' next year
ENDIF
d=1 ' reset date
ENDIF
' this part is to try to keep date in step with skipped days when STEP>1:
'IF dsp=d AND msp=m AND ysp=yr THEN g=1 'stop date.
d2=d2+1
IF d2<day AND g=0 THEN 400 'if skipped days not caught up & not stop date
'g'
100
DRAW TEXT INT(d) & " " & mon$(m) & " " & yr AT sw-160, 60
DRAW TEXT "Day#= " & INT(day) AT sw-160, 30
DRAW TEXT "ZOOM" AT sw-60,200
DRAW TEXT "SPEED" AT 5,200
SET BUTTONS CUSTOM
'-------------------- SCALE ------------
'FILL COLOR 0, 0, .3
'dsc=dscale*.3*(SLIDER_VALUE("scale"))+.024
dsc=dscale*.95*(SLIDER_VALUE("scale"))^2+.03 ' display scale factor
FILL COLOR 1,1, 0 ' yellow, for sun
FILL CIRCLE sw2, sh2 SIZE 25*dsc 'Sun, variable size, according to zoom
DRAW COLOR 1,1, 1 ' white, for planets & orbits
' ===== ORBITS -------------------------------------
FOR i=1 TO 8
DRAW CIRCLE sw2,sh2 SIZE dist(i)*2*dsc 'draw orbits of 8 planets
NEXT i
'Pluto's orbit is elliptical; depict as off centre circle:
poffx=56 ! poffy=-73 'these variables make it easier to adjust all pxoff & pyoff's
DRAW CIRCLE sw2+poffx, sh2+poffy SIZE 5900*2*dsc
'b' ===== PLANETS ========================
FOR i=1 TO 10
FILL COLOR 1,1,1 'white, for planets
IF i=3 THEN FILL COLOR .2, .2, 1 'blue, for Earth only
IF i=4 THEN FILL COLOR 1, .5, .5 'reddish, for Mars only
IF i=7 THEN FILL COLOR .4, 1, .4 'greenish, for Uranus only
IF g=0 THEN pang(i)=pang(i)+ovel(i)*STEP 'new angular pos each day (or each STEP in FOR loop)
IF pang(i)<0 THEN pang(i)=pang(i)+360 ' Make angle positive (for MOD to work)
pang(i)=pang(i)%360 ' a%b is a MOD b
sz=8 'planet size
IF i<=4 OR i=9 THEN sz=4 ' inner planets & Pluto are smaller
IF i=9 THEN 'Pluto
pxoff=poffx ! pyoff=poffy 'pluto offset, to simulate ellipse
ELSE
pxoff=0 ! pyoff=0
ENDIF
' planets only: dsc is the drawing scale
IF i<=9 THEN
x(i)=dist(i)*2*COS(pang(i))*dsc + pxoff ' dist to planet from sun; x position
y(i)=dist(i)*2*SIN(pang(i))*dsc + pyoff
FILL CIRCLE sw2+x(i), sh2+y(i) SIZE sz 'draw planets
DRAW TEXT LEFT$(pname$(i),2) AT sw2+x(i), sh2+y(i)+8 'place below planet
ELSE 'i=10 is the moon
DRAW CIRCLE sw2+x(3), sh2+y(3) SIZE dist(10)*2*dsc 'MOON ORBIT, ctr on Earth
' MOON POS'N: ----------
x(10)=sw2+x(3)+dist(10)*2*COS(pang(10))*dsc 'posn in orbit
y(10)=sh2+y(3)+dist(10)*2*SIN(pang(10))*dsc
FILL CIRCLE x(10),y(10) SIZE 5*dsc 'centred at current posn of Earth+dist from E
ENDIF
NEXT i
REFRESH ON 'now update the screen
PAUSE pdelay 'for low speed - pdelay is set by slider("speed")
500
IF BUTTON_PRESSED("toggle") THEN g=1-g ' toggle Pause/Go & button text
IF g=1 THEN
FILL COLOR 0,.8, 0
BUTTON "toggle" TEXT "GO"
PAUSE .5
ENDIF
FILL COLOR 1,0,0
IF g=0 THEN BUTTON "toggle" TEXT "PAUSE"
'PAUSE .7 'only for testing.
IF dsp=d AND msp=m AND ysp=yr THEN g=1 'stop date so stop/pause.
GOTO main
'-------------------------------
DEF dbp ! DEBUG PAUSE ! END DEF 'this is helpful for debugging
END
''