Author Topic: Phases of the Moon  (Read 3495 times)

0 Members and 1 Guest are viewing this topic.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Phases of the Moon
« on: February 23, 2019, 05:05:07 am »
This is a simple little program demonstrating how the phases of the Moon develop depending upon the positions of the Moon and the Sun in the sky.

The view is for an observer in the northern hemisphere looking south - you Southern-hemispherical people would see things upside-down (but then we're not sure what is preventing you from falling off the Earth anyway! - cue for Pete to give his "gravity of the situation" pun).

The dark green foreshortened half-circle at the bottom represents the viewer's horizon: the Sun and Moon rise in the East (left-hand side) and sink in the West.

Of course, the sizes of the Sun and Moon are way, way larger than in the actual sky, but it is the phase of the moon that is the only important factor.  Apart from the phase, all other factors are quite unrealistic.

The program will start with your current time and date and will then proceed minute-by-minute.  The position of the Sun will be correct, but the Moon starts arbitrarily opposite the Sun (full Moon).  The Sun will gradually catch up the Moon, and there will be a total eclipse every complete Moon cycle (27.3 days in this model).

I could have made the program more complex with more realistic factors, but have left it in this state.  It is rather a simple piece of code and I therefore feel slightly embarrassed to foist it upon you.  You will need the moon image.

Code: QB64: [Select]
  1. 'Moon Phases by QWERKEY 02/03/19
  2.  
  3. CONST Radius% = 98, HalfScreenX% = 550, HalfScreenY% = 300, Pi! = 4 * ATN(1)
  4. CONST G! = 0.75, H! = 0.7, Twelve% = 720, MinsStep%% = 2, Delta! = 0.15, Eclipse! = 0.004
  5. _TITLE "Moon Phases"
  6.  
  7. Moon1& = _LOADIMAGE("moon1.png", 32)
  8. TempImg& = _NEWIMAGE(2 * Radius% + 1, 2 * Radius% + 1, 32)
  9. _DEST TempImg&
  10. _PUTIMAGE (0, 0)-(2 * Radius%, 2 * Radius%), Moon1&
  11. Moon& = MakeHardware&(TempImg&)
  12. _FREEIMAGE Moon1&
  13. TempImg& = _NEWIMAGE(2 * Radius% + 1, 2 * Radius% + 1, 32)
  14. _DEST TempImg&
  15. CIRCLE (Radius%, Radius%), Radius%, _RGB32(255, 255, 0)
  16. PAINT (Radius%, Radius%), _RGB32(255, 255, 0)
  17. Sun& = MakeHardware&(TempImg&)
  18. TempImg& = _NEWIMAGE(2 * HalfScreenX% + 1, 2 * HalfScreenX% + 1, 32)
  19. _DEST TempImg&
  20. CIRCLE (HalfScreenX%, HalfScreenX%), HalfScreenX%, _RGB32(0, 50, 0)
  21. PAINT (HalfScreenX%, HalfScreenX%), _RGB32(0, 50, 0)
  22. Ground& = MakeHardware&(TempImg&)
  23.  
  24. DIM Months$(12, 1), Days%(1)
  25. DATA Jan,31,Feb,28,Mar,31,Apr,30,May,31,Jun,30,Jul,31,Aug,31,Sep,30,Oct,31,Nov,30,Dec,31
  26. FOR N% = 1 TO 12
  27.     FOR M% = 0 TO 1
  28.         READ Months$(N%, M%)
  29.     NEXT M%
  30. NEXT N%
  31. Days%(0) = VAL(LEFT$(DATE$, 2))
  32. Days%(1) = VAL(MID$(DATE$, 4, 2))
  33. IF Days%(0) = 2 AND Days%(1) = 29 THEN Days%(1) = 28
  34. NoMins% = INT(TIMER) \ 60
  35. Beta1! = (Twelve% - NoMins%) * Pi! / Twelve%
  36. Beta2! = Beta1! - Pi!
  37.  
  38. SCREEN _NEWIMAGE(2 * HalfScreenX% + 1, 2 * HalfScreenY% + 1, 32)
  39.  
  40.  
  41.     _LIMIT 60
  42.  
  43.     Theta! = Beta1! - Beta2! - 3 * Pi! / 2
  44.     IF Theta! < -3 * Pi! / 2 THEN
  45.         Theta! = Theta! + 2 * Pi!
  46.     ELSEIF Theta! > Pi! / 2 THEN
  47.         Theta! = Theta! - 2 * Pi!
  48.     END IF
  49.  
  50.     IF Beta1! > -Pi! / 2 AND Beta1! < Pi! / 2 THEN
  51.         IF (Theta! < -3 * Pi! / 2 + Eclipse! AND Theta! > -3 * Pi! / 2) OR (Theta! < Pi! / 2 AND Theta! > Pi! / 2 - Eclipse!) THEN
  52.             COLOR _RGB32(255, 255, 255), _RGB32(0, 0, 10)
  53.         ELSE
  54.             COLOR _RGB32(255, 255, 255), _RGB32(0, 0, 250 * (COS(Beta1!)) ^ 0.3)
  55.         END IF
  56.         CLS
  57.     END IF
  58.     IF Beta1! > -Pi! / 2 - Delta! AND Beta1! < Pi! / 2 + Delta! THEN
  59.         X1% = CINT(HalfScreenX% * SIN(-Beta1!))
  60.         Y1% = CINT(2 * HalfScreenY% * G! * COS(-Beta1!))
  61.         _PUTIMAGE (HalfScreenX% + X1% - Radius%, 2 * HalfScreenY% + 1 - Y1% - Radius%), Sun&
  62.     END IF
  63.     IF Beta2! > -Pi! / 2 - Delta! AND Beta2! < Pi! / 2 + Delta! THEN
  64.         TempImg& = _NEWIMAGE(2 * Radius% + 1, 2 * Radius% + 1, 32)
  65.         _DEST TempImg&
  66.         IF Theta! >= -Pi! / 2 THEN
  67.             FOR N% = 0 TO 500
  68.                 Phi! = N% * Pi! / 500
  69.                 PSET (CINT(Radius% * SIN(Phi!) * SIN(-Pi! / 2)) + Radius%, CINT(Radius% * COS(Phi!)) + Radius%), _RGB32(40, 40, 20)
  70.             NEXT N%
  71.             FOR N% = 0 TO 500
  72.                 Phi! = N% * Pi! / 500
  73.                 PSET (CINT(Radius% * SIN(Phi!) * SIN(Theta!)) + Radius%, CINT(Radius% * COS(Phi!)) + Radius%), _RGB32(40, 40, 20)
  74.             NEXT N%
  75.             IF CINT(Radius% * SIN(Pi! / 2) * SIN(Theta!)) > -(Radius% - 1) THEN PAINT (1, Radius%), _RGB32(40, 40, 20)
  76.             _SETALPHA 230, _RGB32(40, 40, 20)
  77.         ELSE
  78.             FOR N% = 0 TO 500
  79.                 Phi! = N% * Pi! / 500
  80.                 PSET (CINT(Radius% * SIN(Phi!) * SIN(Pi! / 2)) + Radius%, CINT(Radius% * COS(Phi!)) + Radius%), _RGB32(40, 40, 20)
  81.             NEXT N%
  82.             Theta2! = Theta! + Pi!
  83.             FOR N% = 0 TO 500
  84.                 Phi! = N% * Pi! / 500
  85.                 PSET (CINT(Radius% * SIN(Phi!) * SIN(Theta2!)) + Radius%, CINT(Radius% * COS(Phi!)) + Radius%), _RGB32(40, 40, 20)
  86.             NEXT N%
  87.             IF CINT(Radius% * SIN(Pi! / 2) * SIN(Theta2!)) < (Radius% - 1) THEN PAINT (2 * Radius% - 1, Radius%), _RGB32(40, 40, 20)
  88.             _SETALPHA 230, _RGB32(40, 40, 20)
  89.         END IF
  90.         Shadow& = MakeHardware&(TempImg&)
  91.         _DEST 0
  92.         X2% = CINT(HalfScreenX% * SIN(-Beta2!))
  93.         Y2% = CINT(2 * HalfScreenY% * G! * COS(-Beta2!))
  94.         _PUTIMAGE (HalfScreenX% + X2% - Radius%, 2 * HalfScreenY% + 1 - Y2% - Radius%), Moon&
  95.         _PUTIMAGE (HalfScreenX% + X2% - Radius%, 2 * HalfScreenY% + 1 - Y2% - Radius%), Shadow&
  96.         _FREEIMAGE Shadow&
  97.     END IF
  98.     _PUTIMAGE (0, (2 * HalfScreenY% + 1) * H!)-(2 * HalfScreenX% + 1, 2 * HalfScreenY% + 1), Ground&, , (0, 0)-(2 * HalfScreenX% + 1, HalfScreenX%)
  99.     LOCATE 1, 1
  100.     IF NoMins% \ 60 <= 9 THEN
  101.         PRINT " 0" + RIGHT$(STR$(NoMins% \ 60), 1) + " "; NoMins% MOD 60;
  102.     ELSE
  103.         PRINT NoMins% \ 60; NoMins% MOD 60;
  104.     END IF
  105.     LOCATE 1, 130: PRINT Months$(Days%(0), 0) + " "; Days%(1);
  106.  
  107.     _DISPLAY
  108.  
  109.     NoMins% = NoMins% + MinsStep%%
  110.     IF NoMins% >= 1440 THEN
  111.         NoMins% = NoMins% - 1440
  112.         Days%(1) = Days%(1) + 1
  113.         IF Days%(1) > VAL(Months$(Days%(0), 1)) THEN
  114.             Days%(1) = 1
  115.             Days%(0) = Days%(0) + 1
  116.             IF Days%(0) > 12 THEN Days%(0) = 1
  117.         END IF
  118.     END IF
  119.     Beta1! = (Twelve% - NoMins%) * Pi! / Twelve% ' Sun
  120.     IF Beta1! < -Pi! THEN Beta1! = Beta1! + 2 * Pi!
  121.     Beta2! = Beta2! - (MinsStep%% * Pi! / Twelve%) + (2 * 0.0001593) 'Moon 27.39days - factor of 2???
  122.     IF Beta2! < -Pi! THEN Beta2! = Beta2! + 2 * Pi!
  123.  
  124.  
  125.  
  126. FUNCTION MakeHardware& (Img&)
  127.     MakeHardware& = _COPYIMAGE(Img&, 33)
  128.     _FREEIMAGE Img&
  129.  
moon1.png
* moon1.png (Filesize: 266.08 KB, Dimensions: 400x400, Views: 254)
screenshot.png
* screenshot.png (Filesize: 87.94 KB, Dimensions: 1114x639, Views: 227)
« Last Edit: March 02, 2019, 06:16:00 am by Qwerkey »

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: Phases of the Moon
« Reply #1 on: February 25, 2019, 08:01:12 am »
Very cool... Love the animations...

I can remember working out the moon's position on a calculator... 40 minutes of buttons and scribbling... just for one location... Then a further few minutes to calculate the phase... This is SO much quicker... Thank you.
Logic is the beginning of wisdom.

FellippeHeitor

  • Guest
Re: Phases of the Moon
« Reply #2 on: February 25, 2019, 08:48:08 am »
Fun to watch, Notley!

Offline Qwerkey

  • Forum Resident
  • Posts: 755
    • View Profile
Re: Phases of the Moon
« Reply #3 on: February 25, 2019, 10:51:33 am »
Not half as much fun as it was to code, Heitor!

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Phases of the Moon
« Reply #4 on: March 04, 2019, 09:41:22 am »
It seems a very precise simulation. Impressive work, Qwerkey!
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials