Inner planets orrery

Post Reply
Dalede
Posts: 131
Joined: Fri Dec 28, 2012 4:00 pm
Location: Grass Valley, CA, USA
Contact:

Inner planets orrery

Post by Dalede »

This is an example program that simulates the orbit rotation of the inner planets around the sun. It is intended to show some of the features of this Basic. There are many different platforms that run iOS and I had intended to make the rotation time approximately the same but there is no timer function so it may behave much faster or slower than it does on my iPad 2. I decided to add a feature that would let you speed up or slow down the rotation so I added some buttons as an example of button use. Just select and copy the program to add it to your copy of Smart Basic. I do not know what the lite version limits are but this program is too big for that version.

Dale

rem the inner planets orrery

REM ------ set user variables
NormSpeed=.2 rem initial value of speedtimer
Info=1 rem show info
Infotime=100 rem time to show info
Font$="Arial-BoldMT"
TextSize=15
option base 1
randomize

def IsLandscape
if screen_height() < screen_width() then
IsLandscape = 1
else
IsLandscape = 0
endif
end def

REM ----- set size of display
GOSUB SetDisplay
graphics
REM background colors
Br=0
Bg=0
Bb=.3
fill color br,bg,bb
fill rect 0,0 to screen_width(),screen_height()

REM ------ identifiers to planets
sun=1 rem FIRST identifier in array
mercury=2
venus=3
earth=4
mars=5
moon=6 rem LAST identifier in array

REM ----- identifiers to orbital data
dia=1 rem diameter (radius)
dist=2 rem distance to center
period=3 rem orbital period
pos=4 rem angular position in radians
speed=5 rem angular speed. Moon=1
radius=6 rem visible size in pixels
size=7 rem orbit radius in pixels
px=8 rem x-position
py=9 rem y-position

REM ------- initiate arrays for text and data
TextLines=6 rem for messages
DIM Name$(moon),Text$(TextLines)
DIM Orbit(moon,py), Color(moon,3)

GOSUB GetData rem read data in arrays
GOSUB InitData rem initiate orbits

rem initiate variables
PI=3.141593
TWO_PI=6.283185
count=0
fill COLOR Br,Bg,Bb

REM ====== start program
GOSUB PrintInfo

loop:
graphics lock
fill color br,bg,bb
fill rect 0,0 to screen_width(),screen_height()
IF Orientation <> IsLandscape THEN rem update if display turned
GOSUB SetDisplay
ENDIF

IF Info and count>Infotime THEN
fill color br,bg,bb
fill rect 0,0 to screen_width(),screen_height()
rem clear initial info on screen
Info=0
ENDIF
FOR p=sun+1 TO moon-1
GOSUB UpdateOrbit
NEXT p
GOSUB UpdateMoon
IF MoonCycle=1 THEN rem cycle completed, adjust speed
GOSUB SetNormSpeed
count=count+1
ENDIF
if islandscape then
draw font size TextSize
draw text text$(6) at 0,0
endif
if Info then gosub Printinfo
GOSUB DrawSun
draw font name Font$
draw font size TextSize
FOR p=sun+1 TO moon-1
GOSUB DrawPlanet
NEXT p
GOSUB DrawMoon
graphics unlock
GOTO loop
END

DrawPlanet:
fill COLOR Color(p,1),Color(p,2),Color(p,3)
fill CIRCLE Orbit(p,px)-orbit(p,size),Orbit(p,py)-orbit(p,size) to Orbit(p,size)+orbit(p,px),orbit(p,size)+orbit(p,py)
draw COLOR 1,1,1
DRAW TEXT Name$(p) at Orbit(p,px)-TextSize,Orbit(p,py)+Orbit(p,size)+2
RETURN

DrawMoon:
fill COLOR Color(moon,1),Color(moon,2),Color(moon,3)
fill CIRCLE orbit(moon,px)-orbit(moon,size),Orbit(moon,py)-orbit(moon,size) to Orbit(moon,size)+orbit(moon,px), orbit(moon,size)+orbit(moon,py)
RETURN

DrawSun:
fill COLOR Color(sun,1),Color(sun,2),Color(sun,3)
fill CIRCLE CenterX-orbit(sun,size),CenterY-orbit(sun,size) to Orbit(sun,size)+CenterX,orbit(sun,size)+CenterY
p=sun
GOSUB UpdateOrbit rem calculate 'sunspot rotation'
draw COLOR rr,rg,rb
draw LINE CenterX,CenterY to Orbit(sun,px),Orbit(sun,py)
RETURN

UpdateOrbit:
Orbit(p,pos)=Orbit(p,pos)+NormSpeed*Orbit(p,speed)
IF Orbit(p,pos) > TWO_PI THEN
Orbit(p,pos)=Orbit(p,pos)-TWO_PI
ENDIF
rem calculate new x and y
Orbit(p,px)=CenterX+Orbit(p,radius)*COS(Orbit(p,pos))
Orbit(p,py)=CenterY-Orbit(p,radius)*SIN(Orbit(p,pos))
RETURN

UpdateMoon:
Orbit(moon,pos)=Orbit(moon,pos)+NormSpeed*Orbit(moon,speed)
IF Orbit(moon,pos) > TWO_PI THEN
Orbit(moon,pos)=Orbit(moon,pos)-TWO_PI
MoonCycle=1
ENDIF
rem calculate new x and y
Orbit(moon,px)=Orbit(earth,px)+Orbit(moon,radius)*COS(Orbit(moon,pos))
Orbit(moon,py)=Orbit(earth,py)-Orbit(moon,radius)*SIN(Orbit(moon,pos))
RETURN

SetNormSpeed:
if button_pressed("plus") then normspeed=normspeed+.05
if button_pressed("minus") then normspeed=abs(normspeed-.05)
RETURN

SetDisplay:
CenterX=INT(Screen_Width()/2)
CenterY=INT(Screen_Height()/2)
Orientation=IsLandscape
button "plus" title "+" at CenterX*1.9, centerY*1.9
button "minus" title "-" at 10,CenterY*1.9
IF IsLandscape THEN
MaxRadius=INT(0.95*CenterY)
ELSE
MaxRadius=INT(0.95*CenterX)
ENDIF
RETURN

InitData:
FOR p=sun TO moon
rem normalize period to moonperiod
Orbit(p,period)=Orbit(p,period)/Orbit(moon,period)
rem set random orbital position
Orbit(p,pos)=RND(7) rem * TWO_PI rem starting point
rem preset speed. Moonspeed=1
Orbit(p,speed)=1/Orbit(p,period)
MaxDist=Orbit(moon-1,dist)
Orbit(p,radius)=maxradius*Orbit(p,dist)/MaxDist
rem calculate relative size
Orbit(p,size)=Orbit(p,dia)/Orbit(moon,dia)
rem calculate x and y
Orbit(p,px)=CenterX+Orbit(p,radius)*COS(Orbit(p,pos))
Orbit(p,py)=CenterY-Orbit(p,radius)*SIN(Orbit(p,pos))
NEXT p
rem set preliminary moonradius to fraction of distance to venus
Orbit(moon,radius)=(Orbit(earth,radius)-Orbit(venus,radius))/6
rem calculate visual size: radius in pixels
Orbit(sun,size)=Orbit(mercury,radius)/4 rem sun should fit in mercury's orbit
Orbit(moon,size)=Orbit(moon,radius)/5 rem moon gets basic size
IF Orbit(moon,size)<1 THEN
Orbit(moon,size)=1
ENDIF
FOR p=sun+1 TO moon-1
Orbit(p,size)=Orbit(p,size)*Orbit(moon,size)
NEXT p
rem set final moondata
Orbit(moon,pos)=0
Orbit(moon,radius)=(Orbit(earth,radius)-Orbit(venus,radius))/3
Orbit(moon,px)=Orbit(earth,px)+Orbit(moon,radius)*COS(Orbit(p,pos))
Orbit(moon,py)=Orbit(earth,py)-Orbit(moon,radius)*SIN(Orbit(p,pos))
rem preset sunspot
Orbit(sun,radius)=Orbit(sun,size)
RETURN

GetData:
FOR n=sun TO moon
READ Name$(n)
NEXT n
FOR n=1 TO TextLines
READ Text$(n)
NEXT n
rem RESTORE rem SystemData
FOR n=1 TO period
FOR p=sun TO moon
READ Orbit(p,n)
NEXT p
NEXT n
FOR p=sun TO moon
FOR n=1 TO 3
READ Color(p,n)
NEXT n
NEXT p
RETURN

PrintInfo:
draw font size TextSize
draw color 1,1,1
FOR n=1 TO 5
draw text Text$(n) at 0,n*TextSize
NEXT n
RETURN

rem ====== Data for sun, planets and moon. Moon is always last!
English:
DATA "Sun","Mercury","Venus","Earth","Mars","Moon"
DATA "The ratios between the"
DATA " – diameters of moon and planets"
DATA " – planetary orbits (not the moon)"
DATA " – orbital periods and sun-rotation"
DATA "are displayed correctly."
DATA "Orbit is larger if program is started in 'portrait' mode."

SystemData:
rem Diameter, Earth=1
DATA 109, 0.382, 0.949, 1, 0.532, 0.273
rem Mean radius of orbit in Astronomical Units
DATA 0, 0.39, 0.72, 1, 1.52, 0.00257
rem Orbital period in earth years
DATA 0.068, 0.24, 0.62, 1, 1.88, 0.075
Colors:
DATA 1,1,0.5, 1,0,1, 0.3,0.3,1, 0.3,1,0.3, 1,0,0, 1,1,0
Attachments
Orrery screen shot.
Orrery screen shot.
photo.PNG (25.36 KiB) Viewed 6442 times

Dalede
Posts: 131
Joined: Fri Dec 28, 2012 4:00 pm
Location: Grass Valley, CA, USA
Contact:

Re: Inner planets orrery

Post by Dalede »

This is a trimmed down version that will just barely work in the lite version. Planets are all one color, earth's moon is missing, scaling support is limited, no rotation support, no names or other text. The features are supported in the lite version but they would make the program too big. The relative orbits and planet sizes are ok. Enjoy.

Dale

rem inner planets orrery
NormSpeed=.2
Font$="Arial-BoldMT"
option base 1
randomize
CenterX=INT(Screen_Width()/2)
CenterY=INT(Screen_Height()/2)
button "plus" title "+" at CenterX*1.9, centerY*1.9
button "minus" title "-" at 10,CenterY*1.9
MaxRadius=INT(0.95*CenterX)
graphics
pos=4
speed=5
radius=6
size=7
px=8
py=9
DIM Orbit(6,py)
GOSUB GetData
FOR p=1 TO 6
Orbit(p,3)=Orbit(p,3)/Orbit(6,3)
Orbit(p,speed)=1/Orbit(p,3)
MaxDist=Orbit(5,2)
Orbit(p,radius)=maxradius*Orbit(p,2)/MaxDist
Orbit(p,size)=Orbit(p,1)/Orbit(6,1)
Orbit(p,px)=centerx+Orbit(p,radius)*COS(Orbit(p,pos))
Orbit(p,py)=centery-Orbit(p,radius)*SIN(Orbit(p,pos))
NEXT p
PI=3.141593
TWO_PI=6.283185

loop:
graphics lock
graphics clear
FOR p=2 TO 5
GOSUB UpdateOrbit
NEXT p
if button_pressed("plus") then normspeed=normspeed+.05
if button_pressed("minus") then normspeed=abs(normspeed-.05)
GOSUB DrawSun
FOR p=2 TO 5
GOSUB DrawPlanet
NEXT p
graphics unlock
GOTO loop
END

DrawPlanet:
fill COLOR .3,.3,1
fill CIRCLE Orbit(p,px)-orbit(p,size),Orbit(p,py)-orbit(p,size) to Orbit(p,size)+orbit(p,px),orbit(p,size)+orbit(p,py)
RETURN

DrawSun:
fill COLOR 1,1,.5
fill CIRCLE CenterX-orbit(1,size),CenterY-orbit(1,size) to Orbit(1,size)+CenterX,orbit(1,size)+CenterY
return

UpdateOrbit:
Orbit(p,pos)=Orbit(p,pos)+NormSpeed*Orbit(p,speed)
IF Orbit(p,pos) > TWO_PI THEN
Orbit(p,pos)=Orbit(p,pos)-TWO_PI
ENDIF
Orbit(p,px)=CenterX+Orbit(p,radius)*COS(Orbit(p,pos))
Orbit(p,py)=CenterY-Orbit(p,radius)*SIN(Orbit(p,pos))
RETURN

GetData:
FOR n=1 TO 3
FOR p=1 TO 6
READ Orbit(p,n)
NEXT p
NEXT n
RETURN

DATA 6, 0.764, 1.898, 2, 1.064, 0.25
DATA 0, 0.39, 0.72, 1, 1.52, 0.00257
DATA 0.068, 0.24, 0.62, 1, 1.88, 0.075

Dalede
Posts: 131
Joined: Fri Dec 28, 2012 4:00 pm
Location: Grass Valley, CA, USA
Contact:

Re: Inner planets orrery

Post by Dalede »

Modified to take advantage of 1.5 and have better support for rotating screen. This version will still run on the smart basic lite version.

Dale

rem inner planets orrery lite v. 1.1
begin:
restore
NormSpeed=.2
option base 1
CenterX=INT(Screen_Width()/2)
CenterY=INT(Screen_Height()/2)
button "plus" title "+" at CenterX*1.9, CenterY*1.9
button "minus" title "-" at 10,CenterY*1.9
MaxRadius=INT(0.95*CenterX)
graphics
pos=4
speed=5
radius=6
size=7
px=8
py=9
DIM Orbit(6,py)
GOSUB GetData
FOR p=1 TO 6
Orbit(p,3)=Orbit(p,3)/Orbit(6,3)
Orbit(p,speed)=1/Orbit(p,3)
MaxDist=Orbit(5,2)
Orbit(p,radius)=maxradius*Orbit(p,2)/MaxDist
Orbit(p,size)=Orbit(p,1)/Orbit(6,1)
Orbit(p,px)=centerx+Orbit(p,radius)*COS(Orbit(p,pos))
Orbit(p,py)=centery-Orbit(p,radius)*SIN(Orbit(p,pos))
NEXT p
PI=3.141593
TWO_PI=6.283185

loop:
graphics lock
graphics clear 0,0,.3
FOR p=2 TO 5
GOSUB UpdateOrbit
NEXT p
if button_pressed("plus") then normspeed=normspeed+.05
if button_pressed("minus") then normspeed=abs(normspeed-.05)
fill COLOR 1,1,.5
fill CIRCLE CenterX-orbit(1,size),CenterY-orbit(1,size) to Orbit(1,size)+CenterX,orbit(1,size)+CenterY
FOR p=2 TO 5
GOSUB DrawPlanet
NEXT p
graphics unlock
if 2*CenterX <> screen_width() then begin
GOTO loop
END

DrawPlanet:
fill COLOR .3,.3,1
fill CIRCLE Orbit(p,px)-orbit(p,size),Orbit(p,py)-orbit(p,size) to Orbit(p,size)+orbit(p,px),orbit(p,size)+orbit(p,py)
RETURN

UpdateOrbit:
Orbit(p,pos)=Orbit(p,pos)+NormSpeed*Orbit(p,speed)
IF Orbit(p,pos) > TWO_PI THEN
Orbit(p,pos)=Orbit(p,pos)-TWO_PI
ENDIF
Orbit(p,px)=CenterX+Orbit(p,radius)*COS(Orbit(p,pos))
Orbit(p,py)=CenterY-Orbit(p,radius)*SIN(Orbit(p,pos))
RETURN

GetData:
FOR n=1 TO 3
FOR p=1 TO 6
READ Orbit(p,n)
NEXT p
NEXT n
RETURN
DATA 6, 0.764, 1.898, 2, 1.064, 0.25
DATA 0, 0.39, 0.72, 1, 1.52, 0.00257
DATA 0.068, 0.24, 0.62, 1, 1.88, 0.075

User avatar
Dutchman
Posts: 858
Joined: Mon May 06, 2013 9:21 am
My devices: iMac, iPad Air, iPhone
Location: Netherlands
Flag: Netherlands

Re: Inner planets orrery

Post by Dutchman »

DaleDe, you could have given some credit to me.
It is a stripped version of my 'Copernicus heritage' from the Basic! forum :twisted:

Dalede
Posts: 131
Joined: Fri Dec 28, 2012 4:00 pm
Location: Grass Valley, CA, USA
Contact:

Re: Inner planets orrery

Post by Dalede »

Sorry, you are correct. I should have mentioned this.

Dale

Henko
Posts: 816
Joined: Tue Apr 09, 2013 12:23 pm
My devices: iPhone,iPad
Windows
Location: Groningen, Netherlands
Flag: Netherlands

Re: Inner planets orrery

Post by Henko »

[quote="Dalede" There are many different platforms that run iOS and I had intended to make the rotation time approximately the same but there is no timer function so it may behave much faster or slower than it does on my iPad 2.[/quote]

There is a timer function, see the manual, and it is working properly.

Dalede
Posts: 131
Joined: Fri Dec 28, 2012 4:00 pm
Location: Grass Valley, CA, USA
Contact:

Re: Inner planets orrery

Post by Dalede »

Yes the timer function works now but it did not when I first did the port. I ported this basic version to learn the differences needed to make Basic! code work on Smart Basic. So several things were modified, it was a good learning experience.

Dale

Post Reply