All Projects

Airplane Shadow

Try It

It is really special to find yourself in the shadow of an airplane. For a split second you are engulfed in shade by a 200 ton machine flying overhead.

I was curious if it was possible to predict when and where the shadow will fall so I could increase my chances of experiencing this phenomenon, and naturally this led to developing a application to see exactly that.

To calculate the position of a shadow you need three variables:

After brushing some rust off my trigonometry, you can use the following equation to calculate where the shadow will fall:

$\text{Shadow length} = \dfrac{\text{Height}}{\tan(\theta_{\text{sun}})}$

Once I had this equation it was only a matter of plugging in the correct variables and projecting them on a web map in a UI.

Live airplane information is retrieved via the  Airlabs API, and the Suncalc JavaScript library supplies the position of the sun in degrees of altitude and azimuth.

The whole application is written in JavaScript and runs entirely in the browser, no backend needed.

Validation

After putting all the pieces together in the web interface I could reliably project where the plane’s shadow would fall at different times throughout the day, as the location of the sun changes relative to the constant approach path of the plane.

But all of this so far was only bedroom tinkering, it was time to head out into the world and see if any of this really works.

Loading the site on my phone I headed out to the beach, situated myself squarely in the expected trajectory and waited for a plane to approach.

Beach

It worked!

This was a really fun project, a mix of software and the real world. It shows the best part of my work, taking an abstract idea, wondering if it is even possible, and bringing it to life.

Plane UI

Try It

Tools

function shadowCalcPoint(time, lat1, lon1, ele) {
    const sunpos = SunCalc.getPosition(time, lat1, lon1)
    // 0 is south so 180 needs to be divided to flip
    const sunazi = ((sunpos.azimuth * (180.0 / Math.PI))) 
    const sunalt = (sunpos.altitude * 180.0 / Math.PI)
    const shadowlen = (ele / Math.tan(sunpos.altitude))
    const endpoint = new LatLon(lat1, lon1).destinationPoint(shadowlen, (sunazi))

    const lat2 = endpoint._lat
    const lon2 = endpoint._lon
    return [lat2, lon2]
}