Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
3D Sun-Earth-Moon Simulation
#1
This program simulates the Earth and Moon orbiting the sun, and uses _MAPTRIANGLE(3D) to give a full 3D simulation.  This is the last of my _MAPTRIANGLE - Conic Sections quartet of programs (Rotating Cylinders in 3D Space,3D Rolling Sphere,3D Rocket Launch to the Moon).
Unzip the folder into the QB64 directory.

.zip   3D-Sun-Earth-Moon.zip (Size: 5.52 MB / Downloads: 45)
The Earth orbits the sun by Newtonian gravitation (inverse square law).  The mathematics is set to give a pronounced elliptical orbit (the ellipse completes the Conic Sections set) - in reality the Earth's orbit is nearly circular.
The Moon orbits the Earth in a set circular path (not set by gravitation).
The Earth spins on its axis and is tilted at 23.4° to the orbit, exactly as reality.  The period for one revolution defines the day, and the Earth completes its orbit around the Sun in 365.25 days, exactly as reality.
The Moon spins on its axis and keeps the same face to the Earth, exactly as reality.  The Moon takes 27 days to orbit the Earth, exactly as reality.
The Sun spins on its axis.  Because it is a plasma-y object, its spins faster at its equator than at its poles and this is simulated in the program.
Compromises were required.  Clearly the size of the objects bears no relation to the orbits in reality.  A large window is required to show the motions, and even so the Earth and Moon disappear at the left- and right-hand sides.  A video of the running program is attached if your screen is too small to view the whole window.





Because it takes 365.25 Earth days for a complete orbit, the program runs for about 4½ minutes to complete a revolution.
Further enhancements could have been coded (eg altering viewing angles by arrow keys) but the program as is demonstrates the principles.
   

Code: (Select All)
'3D Sun-Earth-Moon Simulation [_MAPTRIANGLE(3D] by Magdha QB64 v2.0 12/11/25
'Parameter set to give correct orbit times for Earth around Sun and Moon around Earth
'The Earth is tilted correctly.  The Moon Orbit has correct tilt, and Moon keeps constant face to Earth
'The Sun has more rapid spin at its equator cf its poles

CONST False = 0, True = NOT False

CONST NoPhis%% = 32, NoThetas%% = 4, NoImages%% = 16, Phi! = _PI / NoPhis%%, Theta! = 2 * _PI / (NoImages%% * NoThetas%%)
CONST ImageRad% = 250, SunRad% = 200, EarthRad% = 100, MoonRad% = 40, ZOffset% = 1800, EarthTilt! = 23.4 * _PI / 180
CONST MoonTilt! = 5.15 * _PI / 180, M1% = 10000, g! = 9.81, RMoon% = 200, MoonOmega! = 0.00533 * 2
CONST SunPoles! = 0.00411, SunEquator! = 0.00164, SunRot! = 0.144

DIM MapFromImage%(NoPhis%%, NoThetas%%, 1), MapToSphere!(2, NoPhis%%, NoImages%% * NoThetas%%, 2)
DIM SunSpot&(NoImages%%), Moony&(NoImages%%), Earthling&(NoImages%%), SunSpin!(NoPhis%%)

_TITLE "3d Sun-Earth-Moon Esc to Quit"

'Load Images and Map to 3D
FOR K%% = 1 TO NoImages%%
    Filename$ = "HSun" + LTRIM$(STR$(K%%)) + ".jpg"
    PRINT Filename$
    TempImage& = _LOADIMAGE(Filename$, 32)
    TempImage1& = _NEWIMAGE(251, 501, 32)
    _DEST TempImage1&
    _PUTIMAGE , TempImage&
    SunSpot&(K%%) = HardwareImage&(TempImage1&, True)
    _FREEIMAGE TempImage&
    Filename$ = "HMoon" + LTRIM$(STR$(K%%)) + ".jpg"
    PRINT Filename$
    TempImage& = _LOADIMAGE(Filename$, 32)
    TempImage1& = _NEWIMAGE(251, 501, 32)
    _DEST TempImage1&
    _PUTIMAGE , TempImage&
    Moony&(K%%) = HardwareImage&(TempImage1&, True)
    _FREEIMAGE TempImage&
    Filename$ = "HEarth" + LTRIM$(STR$(K%%)) + ".jpg"
    PRINT Filename$
    TempImage& = _LOADIMAGE(Filename$, 32)
    TempImage1& = _NEWIMAGE(251, 501, 32)
    _DEST TempImage1&
    _PUTIMAGE , TempImage&
    Earthling&(K%%) = HardwareImage&(TempImage1&, True)
    _FREEIMAGE TempImage&
    FOR N%% = 0 TO NoPhis%%
        FOR M%% = 0 TO NoThetas%%
            'Sun Mapping not required as this is handles in running motion
            'MapToSphere!(0, N%%, M%% + (K%% - 1) * NoThetas%%, 0) = SunRad% * SIN(N%% * Phi!) * SIN((M%% + (K%% - 1) * NoThetas%%) * Theta!) 'x Sphere
            'MapToSphere!(0, N%%, M%% + (K%% - 1) * NoThetas%%, 1) = SunRad% * COS(N%% * Phi!) 'y Sphere
            'MapToSphere!(0, N%%, M%% + (K%% - 1) * NoThetas%%, 2) = SunRad% * SIN(N%% * Phi!) * COS((M%% + (K%% - 1) * NoThetas%%) * Theta!) 'z Sphere
            'Earth Mapping
            MapToSphere!(1, N%%, M%% + (K%% - 1) * NoThetas%%, 0) = EarthRad% * SIN(N%% * Phi!) * SIN((M%% + (K%% - 1) * NoThetas%%) * Theta!) 'x Sphere
            MapToSphere!(1, N%%, M%% + (K%% - 1) * NoThetas%%, 1) = EarthRad% * COS(N%% * Phi!) 'y Sphere
            MapToSphere!(1, N%%, M%% + (K%% - 1) * NoThetas%%, 2) = EarthRad% * SIN(N%% * Phi!) * COS((M%% + (K%% - 1) * NoThetas%%) * Theta!) 'z Sphere
            'Moon Mapping
            MapToSphere!(2, N%%, M%% + (K%% - 1) * NoThetas%%, 0) = MoonRad% * SIN(N%% * Phi!) * SIN((M%% + (K%% - 1) * NoThetas%%) * Theta!) 'x Sphere
            MapToSphere!(2, N%%, M%% + (K%% - 1) * NoThetas%%, 1) = MoonRad% * COS(N%% * Phi!) 'y Sphere
            MapToSphere!(2, N%%, M%% + (K%% - 1) * NoThetas%%, 2) = MoonRad% * SIN(N%% * Phi!) * COS((M%% + (K%% - 1) * NoThetas%%) * Theta!) 'z Sphere
        NEXT M%%
    NEXT N%%
NEXT K%%
'Mapping from Input Images
FOR N%% = 0 TO NoPhis%%
    FOR M%% = 0 TO NoThetas%%
        MapFromImage%(N%%, M%%, 0) = CINT(1.4 * ImageRad% * SIN(N%% * Phi!) * SIN(M%% * Theta!)) 'x Image: 1.4 best compromise
        MapFromImage%(N%%, M%%, 1) = CINT(ImageRad% - ImageRad% * COS(N%% * Phi!)) 'y Image
    NEXT M%%
NEXT N%%

'Background Image
TempImage& = _NEWIMAGE(1900, 1000, 32)
_DEST TempImage&
COLOR _RGB32(200, 200, 200), _RGB32(0, 60, 0)
CLS
Background& = HardwareImage&(TempImage&, True)

'Screen
SCREEN _NEWIMAGE(1900, 1000, 32)
_SCREENMOVE 10, 0
_DEST 0
COLOR _RGB32(255, 255, 255)
CLS
_DISPLAYORDER _SOFTWARE , _HARDWARE 'Doesn't display software Days no matter what

K%% = 1
Count& = 0
XSun! = 400
YSun! = 0
ZSun! = 0
XEarth! = XSun! + DXEarth!
YEarth! = YSun! + DYEarth!
ZEarth! = ZSun! + DZEarth!
DXStart! = 700
DXEarth! = DXStart!
VzStart! = -SQR(g! * M1% / 500)
Vx! = 0
Vz! = VzStart!
deltaT! = 0.05
EarthThetaOld! = 0
DYEarth! = 0
DZEarth! = 0
MoonTheta! = 0

SolarSystem%% = True
WHILE SolarSystem%%
    K1$ = INKEY$
    IF K1$ <> "" THEN
        IF ASC(K1$) = 27 THEN SolarSystem%% = False
    END IF
    K1$ = ""
    _LIMIT 60

    _PUTIMAGE , Background&
    'LOCATE 1, 1 'Want to print days
    'PRINT EarthDays%
    Count& = Count& + 1

    'Display Images
    FOR K%% = 1 TO NoImages%%
        FOR N%% = 1 TO NoPhis%%
            FOR M%% = 1 TO NoThetas%%

                'The Sun
                'Sun spins on its axis, faster at the equator
                SunSpin!(N%%) = SunSpin(N%%) + 0.03 * (SunPoles! + SIN(N%% * Phi!) * SunEquator!)
                dx1! = SunRad% * SIN((N%% - 1) * Phi!) * SIN(SunSpin!(N%%) + (M%% - 1 + (K%% - 1) * NoThetas%%) * Theta!)
                dy1! = SunRad% * COS((N%% - 1) * Phi!)
                dz1! = SunRad% * SIN((N%% - 1) * Phi!) * COS(SunSpin!(N%%) + (M%% - 1 + (K%% - 1) * NoThetas%%) * Theta!)
                dx2! = SunRad% * SIN((N%% - 1) * Phi!) * SIN(SunSpin!(N%%) + (M%% + (K%% - 1) * NoThetas%%) * Theta!)
                dy2! = SunRad% * COS((N%% - 1) * Phi!)
                dz2! = SunRad% * SIN((N%% - 1) * Phi!) * COS(SunSpin!(N%%) + (M%% + (K%% - 1) * NoThetas%%) * Theta!)
                dx3! = SunRad% * SIN(N%% * Phi!) * SIN(SunSpin!(N%%) + (M%% + (K%% - 1) * NoThetas%%) * Theta!)
                dy3! = SunRad% * COS(N%% * Phi!)
                dz3! = SunRad% * SIN(N%% * Phi!) * COS(SunSpin!(N%%) + (M%% + (K%% - 1) * NoThetas%%) * Theta!)
                dx4! = SunRad% * SIN(N%% * Phi!) * SIN(SunSpin!(N%%) + (M%% - 1 + (K%% - 1) * NoThetas%%) * Theta!)
                dy4! = SunRad% * COS(N%% * Phi!)
                dz4! = SunRad% * SIN(N%% * Phi!) * COS(SunSpin!(N%%) + (M%% - 1 + (K%% - 1) * NoThetas%%) * Theta!)
                _MAPTRIANGLE (MapFromImage%(N%% - 1, M%% - 1, 0), MapFromImage%(N%% - 1, M%% - 1, 1))-(MapFromImage%(N%% - 1, M%%, 0), MapFromImage%(N%% - 1, M%%, 1))-(MapFromImage%(N%%, M%%, 0), MapFromImage%(N%%, M%%, 1)), SunSpot&(K%%) TO(dx1! + XSun!, dy1! + YSun!, dz1! + ZSun! - ZOffset%)-(dx2! + XSun!, dy2! + YSun!, dz2! + ZSun! - ZOffset%)-(dx3! + XSun!, dy3! + YSun!, dz3! + ZSun! - ZOffset%)
                _MAPTRIANGLE (MapFromImage%(N%%, M%%, 0), MapFromImage%(N%%, M%%, 1))-(MapFromImage%(N%%, M%% - 1, 0), MapFromImage%(N%%, M%% - 1, 1))-(MapFromImage%(N%% - 1, M%% - 1, 0), MapFromImage%(N%% - 1, M%% - 1, 1)), SunSpot&(K%%) TO(dx3! + XSun!, dy3! + YSun!, dz3! + ZSun! - ZOffset%)-(dx4! + XSun!, dy4! + YSun!, dz4! + ZSun! - ZOffset%)-(dx1! + XSun!, dy1! + YSun!, dz1! + ZSun! - ZOffset%)

                'The Earth
                x1! = MapToSphere!(1, N%% - 1, M%% - 1 + (K%% - 1) * NoThetas%%, 0)
                z1! = MapToSphere!(1, N%% - 1, M%% - 1 + (K%% - 1) * NoThetas%%, 2)
                y1! = MapToSphere!(1, N%% - 1, M%% - 1 + (K%% - 1) * NoThetas%%, 1)
                x2! = MapToSphere!(1, N%% - 1, M%% + (K%% - 1) * NoThetas%%, 0)
                z2! = MapToSphere!(1, N%% - 1, M%% + (K%% - 1) * NoThetas%%, 2)
                y2! = MapToSphere!(1, N%% - 1, M%% + (K%% - 1) * NoThetas%%, 1)
                x3! = MapToSphere!(1, N%%, M%% + (K%% - 1) * NoThetas%%, 0)
                z3! = MapToSphere!(1, N%%, M%% + (K%% - 1) * NoThetas%%, 2)
                y3! = MapToSphere!(1, N%%, M%% + (K%% - 1) * NoThetas%%, 1)
                x4! = MapToSphere!(1, N%%, M%% - 1 + (K%% - 1) * NoThetas%%, 0)
                z4! = MapToSphere!(1, N%%, M%% - 1 + (K%% - 1) * NoThetas%%, 2)
                y4! = MapToSphere!(1, N%%, M%% - 1 + (K%% - 1) * NoThetas%%, 1)
                'Rotate Earth (y-axis)
                x11! = x1! * COS(EarthOmega!) + z1! * SIN(EarthOmega!)
                z11! = -x1! * SIN(EarthOmega!) + z1! * COS(EarthOmega!)
                x21! = x2! * COS(EarthOmega!) + z2! * SIN(EarthOmega!)
                z21! = -x2! * SIN(EarthOmega!) + z2! * COS(EarthOmega!)
                x31! = x3! * COS(EarthOmega!) + z3! * SIN(EarthOmega!)
                z31! = -x3! * SIN(EarthOmega!) + z3! * COS(EarthOmega!)
                x41! = x4! * COS(EarthOmega!) + z4! * SIN(EarthOmega!)
                z41! = -x4! * SIN(EarthOmega!) + z4! * COS(EarthOmega!)
                y11! = y1!
                y21! = y2!
                y31! = y3!
                y41! = y4!
                'Tilt Earth (z-axis rotation)
                dx1! = x11! * COS(EarthTilt!) + y11! * SIN(EarthTilt!)
                dy1! = -x11! * SIN(EarthTilt!) + y11! * COS(EarthTilt!)
                dx2! = x21! * COS(EarthTilt!) + y21! * SIN(EarthTilt!)
                dy2! = -x21! * SIN(EarthTilt!) + y21! * COS(EarthTilt!)
                dx3! = x31! * COS(EarthTilt!) + y31! * SIN(EarthTilt!)
                dy3! = -x31! * SIN(EarthTilt!) + y31! * COS(EarthTilt!)
                dx4! = x41! * COS(EarthTilt!) + y41! * SIN(EarthTilt!)
                dy4! = -x41! * SIN(EarthTilt!) + y41! * COS(EarthTilt!)
                dz1! = z11!
                dz2! = z21!
                dz3! = z31!
                dz4! = z41!
                _MAPTRIANGLE (MapFromImage%(N%% - 1, M%% - 1, 0), MapFromImage%(N%% - 1, M%% - 1, 1))-(MapFromImage%(N%% - 1, M%%, 0), MapFromImage%(N%% - 1, M%%, 1))-(MapFromImage%(N%%, M%%, 0), MapFromImage%(N%%, M%%, 1)), Earthling&(K%%) TO(dx1! + XEarth!, dy1! + YEarth!, dz1! + ZEarth! - ZOffset%)-(dx2! + XEarth!, dy2! + YEarth!, dz2! + ZEarth! - ZOffset%)-(dx3! + XEarth!, dy3! + YEarth!, dz3! + ZEarth! - ZOffset%)
                _MAPTRIANGLE (MapFromImage%(N%%, M%%, 0), MapFromImage%(N%%, M%%, 1))-(MapFromImage%(N%%, M%% - 1, 0), MapFromImage%(N%%, M%% - 1, 1))-(MapFromImage%(N%% - 1, M%% - 1, 0), MapFromImage%(N%% - 1, M%% - 1, 1)), Earthling&(K%%) TO(dx3! + XEarth!, dy3! + YEarth!, dz3! + ZEarth! - ZOffset%)-(dx4! + XEarth!, dy4! + YEarth!, dz4! + ZEarth! - ZOffset%)-(dx1! + XEarth!, dy1! + YEarth!, dz1! + ZEarth! - ZOffset%)

                'The Moon
                XMoon! = XEarth! + RMoon% * COS(MoonTheta!) * COS(MoonTilt!)
                ZMoon! = ZEarth! + RMoon% * SIN(MoonTheta!) * COS(MoonTilt!)
                YMoon! = YEarth! + RMoon% * COS(MoonTheta!) * SIN(MoonTilt!)
                x1! = MapToSphere!(2, N%% - 1, M%% - 1 + (K%% - 1) * NoThetas%%, 0)
                z1! = MapToSphere!(2, N%% - 1, M%% - 1 + (K%% - 1) * NoThetas%%, 2)
                y1! = MapToSphere!(2, N%% - 1, M%% - 1 + (K%% - 1) * NoThetas%%, 1)
                x2! = MapToSphere!(2, N%% - 1, M%% + (K%% - 1) * NoThetas%%, 0)
                z2! = MapToSphere!(2, N%% - 1, M%% + (K%% - 1) * NoThetas%%, 2)
                y2! = MapToSphere!(2, N%% - 1, M%% + (K%% - 1) * NoThetas%%, 1)
                x3! = MapToSphere!(2, N%%, M%% + (K%% - 1) * NoThetas%%, 0)
                z3! = MapToSphere!(2, N%%, M%% + (K%% - 1) * NoThetas%%, 2)
                y3! = MapToSphere!(2, N%%, M%% + (K%% - 1) * NoThetas%%, 1)
                x4! = MapToSphere!(2, N%%, M%% - 1 + (K%% - 1) * NoThetas%%, 0)
                z4! = MapToSphere!(2, N%%, M%% - 1 + (K%% - 1) * NoThetas%%, 2)
                y4! = MapToSphere!(2, N%%, M%% - 1 + (K%% - 1) * NoThetas%%, 1)
                'Rotate Moon (y-axis) in opposite direction to its orbit: it keeps the same face towards Earth
                MoonAngle! = -MoonTheta!
                dx1! = x1! * COS(MoonAngle!) + z1! * SIN(MoonAngle!)
                dz1! = -x1! * SIN(MoonAngle!) + z1! * COS(MoonAngle!)
                dx2! = x2! * COS(MoonAngle!) + z2! * SIN(MoonAngle!)
                dz2! = -x2! * SIN(MoonAngle!) + z2! * COS(MoonAngle!)
                dx3! = x3! * COS(MoonAngle!) + z3! * SIN(MoonAngle!)
                dz3! = -x3! * SIN(MoonAngle!) + z3! * COS(MoonAngle!)
                dx4! = x4! * COS(MoonAngle!) + z4! * SIN(MoonAngle!)
                dz4! = -x4! * SIN(MoonAngle!) + z4! * COS(MoonAngle!)
                dy1! = y1!
                dy2! = y2!
                dy3! = y3!
                dy4! = y4!
                _MAPTRIANGLE (MapFromImage%(N%% - 1, M%% - 1, 0), MapFromImage%(N%% - 1, M%% - 1, 1))-(MapFromImage%(N%% - 1, M%%, 0), MapFromImage%(N%% - 1, M%%, 1))-(MapFromImage%(N%%, M%%, 0), MapFromImage%(N%%, M%%, 1)), Moony&(K%%) TO(dx1! + XMoon!, dy1! + YMoon!, dz1! + ZMoon! - ZOffset%)-(dx2! + XMoon!, dy2! + YMoon!, dz2! + ZMoon! - ZOffset%)-(dx3! + XMoon!, dy3! + YMoon!, dz3! + ZMoon! - ZOffset%)
                _MAPTRIANGLE (MapFromImage%(N%%, M%%, 0), MapFromImage%(N%%, M%%, 1))-(MapFromImage%(N%%, M%% - 1, 0), MapFromImage%(N%%, M%% - 1, 1))-(MapFromImage%(N%% - 1, M%% - 1, 0), MapFromImage%(N%% - 1, M%% - 1, 1)), Moony&(K%%) TO(dx3! + XMoon!, dy3! + YMoon!, dz3! + ZMoon! - ZOffset%)-(dx4! + XMoon!, dy4! + YMoon!, dz4! + ZMoon! - ZOffset%)-(dx1! + XMoon!, dy1! + YMoon!, dz1! + ZMoon! - ZOffset%)

            NEXT M%%
        NEXT N%%
    NEXT K%%

    _DISPLAY

    'Motions and Rotations
    'Earth Rotation (one complete revolution = 1 day)
    EarthOmega! = EarthOmega! + SunRot!
    IF EarthOmega! > _PI THEN
        EarthOmega! = EarthOmega! - 2 * _PI
        EarthDays% = EarthDays% + 1
    END IF
    'Move the Moon relative to Earth in a tilted circular orbit
    MoonTheta! = MoonTheta! - MoonOmega! '* deltaT!
    IF MoonTheta! < -_PI THEN
        MoonTheta! = MoonTheta! + 2 * _PI
        MoonDays% = MoonDays% + 1
    END IF
    EarthTheta! = _ATAN2(DZEarth!, DXEarth!)

    IF EarthThetaOld! > 0 AND EarthTheta! <= 0 THEN
        'Reset at complete orbital revoltion (slight error in ellipse calculations)
        DXEarth! = DXStart!
        DZEarth! = 0
        Vx! = 0
        Vz! = VzStart!
        EarthTheta! = 0
        EarthThetaOld! = 0
    ELSE
        'Gravitational calculations for Earth's orbit
        R! = SQR(DXEarth! * DXEarth! + DZEarth! * DZEarth!)
        A! = g! * M1% / (R! * R!)
        Ax! = -A! * COS(EarthTheta!)
        Az! = -A! * SIN(EarthTheta!)
        deltaVx! = Ax! * deltaT!
        deltaVz! = Az! * deltaT!
        Vx! = Vx! + deltaVx!
        Vz! = Vz! + deltaVz!
        DXEarth! = DXEarth! + (Vx! + deltaVx! / 2) * deltaT!
        DZEarth! = DZEarth! + (Vz! + deltaVz! / 2) * deltaT!
        EarthThetaOld! = EarthTheta!
        XEarth! = XSun! + DXEarth!
        ZEarth! = ZSun! + DZEarth!
    END IF

WEND

SYSTEM

FUNCTION HardwareImage& (ImageName&, Scrap%%)
    HardwareImage& = _COPYIMAGE(ImageName&, 33)
    IF Scrap%% THEN _FREEIMAGE ImageName&
END FUNCTION
Reply


Messages In This Thread
3D Sun-Earth-Moon Simulation - by Magdha - 11-12-2025, 01:03 PM
RE: 3D Sun-Earth-Moon Simulation - by bplus - 11-12-2025, 02:20 PM
RE: 3D Sun-Earth-Moon Simulation - by Magdha - 11-14-2025, 10:57 AM
RE: 3D Sun-Earth-Moon Simulation - by Dav - 11-14-2025, 12:29 PM
RE: 3D Sun-Earth-Moon Simulation - by 2112 - 11-14-2025, 05:00 PM
RE: 3D Sun-Earth-Moon Simulation - by bplus - 11-14-2025, 07:07 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Fairground Duck Shoot Simulation Game Magdha 10 504 01-26-2026, 01:25 PM
Last Post: Dav
  Gravitation Simulation Magdha 0 210 12-24-2025, 10:00 AM
Last Post: Magdha
  Moon Phases Magdha 0 227 11-25-2025, 11:34 AM
Last Post: Magdha
  3D Rocket Launch to the Moon Magdha 0 272 11-03-2025, 01:05 PM
Last Post: Magdha

Forum Jump:


Users browsing this thread: 1 Guest(s)