SIMULATION / FREE / MIT EXAMPLE SOURCE

Little worlds

Eight places to wander

A smooth solar navigator with original clay-like planets, prograde orbits, and correctly directed axial spins, including Venus and Uranus.

Little worlds, running as a native Yeho application on Windows
Actual native application capture. The downloadable source produces this example.

Take it for a spin.

Select a planet on the canvas or use its button. Up/Down zoom, Space pauses orbital motion, and R returns to the whole system. T switches between rotation study (0.1 Earth day/second) and orbital exploration (10 days/second). Both motions share the same simulation clock.

Extract the Windows download to a writable folder and open solar-system.exe. Escape closes it. Database examples keep their local data in the working folder.

See how it works.

Dolphin trigonometry, orbital periods, camera interpolation, transparent pixel buffers, and procedural sphere lighting.

JPL sidereal periods and approximate NASA axial tilts. Circular coplanar orbits, illustrative initial phases and pole azimuths, compressed radii/distances. No ephemeris, precession, differential atmospheric rotation, or n-body integration; high-speed spins may alias.

Orbital and rotation periods follow JPL’s planetary parameters; approximate axial tilts follow NASA GSFC’s teaching table. Venus and Uranus use their full retrograde obliquities, with one shared simulation clock.

READ / CHANGE / UNDERSTAND

The whole example is yours.

These are the exact files in the source download. Start with the model, then follow the window’s event loop. Comments explain the decisions.

model.yh
using dolphin.math
// Orbital display values are intentionally compressed for exploration.
// Periods are Earth years; this is a navigator, not an n-body physics model.
thing Planet
{
    text name
    float orbit
    float period
    float phase=0
    float spinDays=1
    float tilt=0
    int radius
    int red
    int green
    int blue
    text note
}
PlanetData(text name,float orbit,float period,int radius,int r,int g,int b,text note) returns Planet
{
    Planet p
    p.name=name
    p.orbit=orbit
    p.period=period
    p.radius=radius
    p.red=r
    p.green=g
    p.blue=b
    p.note=note
    ConfigureRotation(p)
    return p
}
WorldX(Planet planet,float years) returns float
{
    return DolphinCosAccurate(OrbitAngle(planet,years))*planet.orbit
}
WorldY(Planet planet,float years) returns float
{
    return -DolphinSinAccurate(OrbitAngle(planet,years))*planet.orbit*0.45
}
// Original procedural clay: a softly lit sphere, broad bands, and small pressed
// dimples. No borrowed character, texture, or franchise artwork is used.
Clay(Planet planet,float days=0.0) returns buffer of int
{
    buffer of int pixels
    pixels.Resize(128*128)
    float angle=SpinAngle(planet,days)
    float cs=DolphinCosAccurate(angle)
    float sn=DolphinSinAccurate(angle)
    float tilt=planet.tilt*0.01745329252
    float ct=DolphinCosAccurate(tilt)
    float st=DolphinSinAccurate(tilt)
    for y from 0 < 128
    {
        for x from 0 < 128
        {
            float nx=Math.IntToFloat(x-64)/61.0
            float ny=Math.IntToFloat(y-64)/61.0
            float rr=nx*nx+ny*ny
            int i=y*128+x
            if rr>1.0
            {
                pixels[i]=0
            }
            else
            {
                float z=Math.SqrtFloat(1.0-rr)
                float light=Math.MaxFloat(0.0,-nx*0.4-ny*0.5+z*0.72)
                // Convert the visible normal into ecliptic coordinates. The camera is
                // above the north side, tilted so orbital circles project to ellipses.
                float wx=nx
                float wy=-ny*0.45+z*0.893028555
                float wz=ny*0.893028555+z*0.45
                // Inverse axial tilt, then inverse spin, samples a pattern attached to
                // the body. The light stays fixed while the clay surface really rotates.
                float qy=wy*ct-wz*st
                float bz=wy*st+wz*ct
                float bx=wx*cs+qy*sn
                float by=-wx*sn+qy*cs
                float bands=DolphinSinAccurate(bz*15.0+bx*2.0)*0.065
                float dimples=DolphinSinAccurate(bx*44.0+by*9.0)*DolphinCosAccurate(bz*37.0)*0.022
                float patch=DolphinSinAccurate(bx*4.0+by*3.0)*DolphinCosAccurate(bz*5.0)*0.10
                bands=bands+patch
                float shade=0.28+light*0.72+bands+dimples
                int r=Math.RoundToInt(Math.ClampFloat(Math.IntToFloat(planet.red)*shade,0.0,255.0))
                int g=Math.RoundToInt(Math.ClampFloat(Math.IntToFloat(planet.green)*shade,0.0,255.0))
                int b=Math.RoundToInt(Math.ClampFloat(Math.IntToFloat(planet.blue)*shade,0.0,255.0))
                pixels[i]=b | (g<<8) | (r<<16) | (255<<24)
            }
        }
    }
    return pixels
}
thing PlanetTexture
{
    buffer of int pixels
}