'THIS ORBIT SIMULATOR USES VECTORS 'IN THIS PROGRAM A VECTOR CONCISTS OF TWO VARIABLES '- THE X PART OF THE VECTOR ENDS WITH X '- THE Y PART OF THE VECTOR ENDS WITH Y ABBREVIATIONS: 'F MEANS FORCE 'M MEANS MASS 'R MEANS RADIUS 'A MEANS ACCELERATION 'V MEANS VELOCITY 'C IS A CONSTANT 'G IS THE GRAVITATIONAL CONSTANT 'IF THIS IS AT THE END OF A VARIABLE: 'E MEANS EARTH 'M MEANS MOON GAMEPAD 1 GLOBAL X,Y,XE,YE,XM,YM,CM,CE,GRAVITY,M,RES2,FG START: 'DEFINE VARIABLES G=6.67384*10^(-11) ME=5.972*10^24 MM=7.35*10^22 M=1000 CE=G*ME*M CM=G*MM*M R=0.0001 POWER=100 POWER2=30 GRAVITY=10^(-12) 'SCALE THE FORCES CE=CE*GRAVITY CM=CM*GRAVITY DT=0.2 XE=80 YE=60 XM=20 YM=60 X=60 Y=40 VX=3 VY=-3 AX=0 AY=0 RX=0 RY=0 FGX=0 FGY=0 RES2=5 N=0 I=0 'WRITE BUTTON A ON TO START PATH DRAWING POKE $FF70,PEEK($FF70)+16 'SET TEXT PALLETTE PAL 1 SUB GFORCE(X,Y,X0,Y0,C,RX,RY,R,FGX,FGY) 'GRAVITATIONAL FORCE 'CALCULATE RADIUS BETWEEN PLANET (XE,YE) AND SATELLITE (X,Y) USING VECTOR LENGTH RX=X0-X RY=Y0-Y R=SQR(RX*RX+RY*RY) 'CALCULATE GRAVITATIONAL FORCE (FG) FG=C/(R*R) 'DECOMPOSE FG USING UNIFORMITY ADD FGX,RX*FG/R ADD FGY,RY*FG/R END SUB DO FGX=0 FGY=0 CALL GFORCE(X,Y,XM,YM,CM,RX,RY,R,FGX,FGY) CALL GFORCE(X,Y,XE,YE,CE,RX,RY,R,FGX,FGY) 'THRUST FORCE (USER INPUT): 'ABSOLUTE (JOYSTICK) + DIRECTIONAL (BUTTONS) (USES A VECTOR PERPENDICULAR TO R) FTX=POWER*(LEFT(0)-RIGHT(0)) - POWER2*RY/R*(BUTTON(0,0)-BUTTON(0,1)) FTY=POWER*(UP(0) -DOWN(0) ) + POWER2*RX/R*(BUTTON(0,0)-BUTTON(0,1)) 'RESULTANT FORCE FX=FTX+FGX FY=FTY+FGY 'TRACE FX,FY 'ACCELERATION AX=FX/M AY=FY/M 'TRACE AX,AY 'VELOCITY ADD VX,AX*DT ADD VY,AY*DT 'TRACE VX,VY 'POSITION ADD X,VX*DT ADD Y,VY*DT 'TRACE X,Y 'MOON XM=60*COS(TIMER*0.005)+78 YM=60*SIN(TIMER*0.005)+58 'DRAW SPRITES SPRITE 0,X,Y,1 SPRITE 1,XE-4,YE-4,2 SPRITE 1 PAL 1 SPRITE 2,XM,YM,3 SPRITE 2 PAL 2 IF SPRITE HIT(0,2) THEN TEXT 2,15,"CONGRATULATIONS" 'DRAW PATH 'IF NO BUTTON AND EVERY NOW AND THEN THEN DRAW THE PATH IF PEEK($FF70)<>0 AND TIMER MOD 2 = 0 THEN CALL PATH(X,Y,VX,VY,RX,RY,R) IF SPRITE HIT(0,1) THEN EXIT IF RES2>30 THEN RES2=1 'EXIT WAIT VBL LOOP GOTO START SUB PATH(X,Y,VX,VY,RX,RY,R) 'TIMEOUT, DYNAMIC RESOLUTION (DELTA T), SPRITE COUNT (RES), AND SPRITE ID (I) TIMEOUT=TIMER+5 DT=0.08*RES2 RES=60 I=0 RX1=0 RY1=0 FGX=0 FGY=0 FX=0 FY=0 'COPY THE VARS X1=X Y1=Y VX1=VX VY1=VY 'CALCULATE THE STARTING ANGLE PHI=((ACOS(RX/SQR(RX*RX+RY*RY))*SGN(RY)+PI)/(2*PI))*61 PHI1=0 REPEAT FX=0 FY=0 'MOON (MAKES THE PATH EVEN MORE GLITCHY) 'CALL GFORCE(X1,Y1,XM,YM,CM,RX1,RY1,R,FX,FY) 'EARTH CALL GFORCE(X1,Y1,XE,YE,CE,RX1,RY1,R,FX,FY) 'ACCELERATION AX=FX/M AY=FY/M 'VELOCITY ADD VX1,AX*DT ADD VY1,AY*DT 'POSITION ADD X1,VX1*DT ADD Y1,VY1*DT 'CALCULATE THE CURRENT ANGLE (RELATIVE TO STARTING ANGLE) PHI1=((((ACOS(RX1/SQR(RX1*RX1+RY1*RY1))*SGN(RY1)+PI)/(2*PI))*RES-PHI)+RES) MOD RES 'AT SPECIFIC ANGLES IF PHI1>I THEN 'DRAW A PIXEL (SPRITE) SPRITE 3+I,X1,Y1,1 SPRITE 3+I PAL 2 ADD I,1,0 TO RES-1 'EARTH HIT! IF SPRITE HIT(3+I,1) THEN TIMEOUT=TIMER+1 END IF UNTIL I=RES-1 OR TIMER>TIMEOUT 'CHANGE THE RESOLUTION BASED ON LAG DATA (IT'S DYNAMIC) IF RES-1>I THEN INC RES2 IF TIMEOUT-TIMER>4 AND RES2>1 THEN DEC RES2 'REMOVE OUTDATED SPRITES SPRITE OFF 3+I TO 63 'VIEW THE DIPYNAMIC RESOLUTION 'TRACE RES2 END SUB SUB TRASH 'IT WAS AN AWFUL LOT OF WORK TO FIGURE OUT HOW TO MAKE A PATH '- IT'S NOT VERY DOABLE TO MAKE AN EXPLICIT FORMULA FROM THESE RECURSIVE FORMULAS '- ATAN(RY/RX) WASN'T EASY TO WORK WITH '- INSTEAD I USED ACOS(RX1/SQR(RX1*RX1+RY1*RY1)) 'AN ATTEMPT TO MAKE AN EXPLICIT FORMULA FROM THESE RECURSIVE FORMULAS 'GRAVITATIONAL FORCE 'CALCULATE RADIUS BETWEEN PLANET (XE,YE) AND SATELLITE (X,Y) USING VECTOR LENGTH 'RX=XE-X 'RY=YE-Y 'R=SQR((XE-X)^2+(YE-Y)^2) 'CALCULATE GRAVITATIONAL FORCE (FG) 'FG=C/((XE-X)^2+(YE-Y)^2) 'DECOMPOSE FG USING UNIFORMITY 'FGX=GRAVITY*(C/((XE-X)^2+(YE-Y)^2)/SQR((XE-X)^2+(YE-Y)^2))*XE-X 'FGY=GRAVITY*(C/((XE-X)^2+(YE-Y)^2)/SQR((XE-X)^2+(YE-Y)^2))*YE-Y 'ACCELERATION 'AX=(FTX+FGX)/M 'AY=(FTY+FGY)/M 'VELOCITY 'VX=N*(FTX+FGX)/M*DT+3 'VY=N*(FTY+FGY)/M*DT-3 'POSITION 'X=N*(N*(FTX+FGX)/M*DT+3)*DT+40 'Y=N*(N*(FTY+FGY)/M*DT-3)*DT+60 'EVERYTHING IN ONE FINAL RECURSIVE FUNCTION 'IN ORDER TO MAKE THIS FUNCTION EXPLICIT X AND Y NEED TO BE ISOLATED 'X=N*(N*(FTX+GRAVITY*(C/((XE-X)^2+(YE-Y)^2)/SQR((XE-X)^2+(YE-Y)^2))*XE-X)/M*DT+3)*DT 'Y=N*(N*(FTY+GRAVITY*(C/((XE-X)^2+(YE-Y)^2)/SQR((XE-X)^2+(YE-Y)^2))*YE-Y)/M*DT-3)*DT 'IN EACH LOOP: 'INC N 'AN ATTEMPT TO MAKE AN ELLYPTIC FORMULA BASED ON SAMPLED VALUES 'SAMPLE THE SATELLITE COORDINATES AND RADIUS RX AND RY EVERY N*DT 'USE THE LAST THREE SAMPLES TO MAKE AN ELLYPTIC FORMULA 'CALCULATE THE ANGLE PHI FOR SAMPLED RX AND RY VALUES 'THIS INFORMATION CAN BE USED TO MAKE AN ELLYPSE 'X=A*COS(PHI)+C 'Y=B*SIN(PHI)+D 'SO 'P1=A*COS(Q1)+C 'P2=A*COS(Q2)+C 'SO 'P1=A*R1+C 'P2=A*R2+C 'C=P2-A*R2 'SO 'P1=A*R1+P2-A*R2 'SO 'P1-P2=A*(R1-R2) 'SO 'A=(P1-P2)/(R1-R2) 'AND 'C=P2-A*R2 'SO 'C=P2-R2*(P1-P2)/(R1-R2) 'DO THE SAME FOR Y 'THIS WILL GIVE ME AN ELLYPSE WHICH IS NOT ROTATED 'ANGLE CALCULATION ATTEMPTS 'PHI1=INT((ATAN(RY1/RX1)+0.5*PI+PI*0.5*(SGN(RX1)+1)/(2*PI))*10) 'TRACE I 'TRACE INT(((ATAN(RY/RX)+0.5*PI+PI*0.5*(SGN(RX)+1))/4)*62) 'TRACE ((ATAN(RY1/RX1)+0.5*PI+PI*0.5*(SGN(RX1)+1))/(2*PI)) 'TRACE ATAN(RY1/RX1) 'TRACE ATAN(RY1/RX1),ATAN(RY/RX) 'TRACE " ",INT(X1),INT(Y1) 'TRACE " ",INT(PHI1),I 'INT(PHI*4)=0 'ATAN(RY/RX)>ATAN(RY1/RX1) 'TRACE "END" 'TRACE RY/RX 'TRACE ATAN(RY/RX)+0.5*PI+PI*0.5*(SGN(RX)+1) 'SATELLITE TRAIL (USED BEFORE PATH) 'TRACE "S",INT(X),INT(Y) 'SPRITE 3+I,X,Y,1 'SPRITE 3+I PAL 2 'ADD I,0.2,0 TO 61 END SUB #1:MAIN PALETTES 00150C3F0008073F003F2A15003F3C00 003F2A15003F2A15003F2A15003F2A15 #2:MAIN CHARACTERS 00000000000000000000000000000000 80000000000000008000000000000000 180067CFCE8400183C7E9830317B7E3C 108848987000000070F8F8F870000000