Solar Analysis¶
IFClite includes pure, dependency-free solar math for BIM sun studies. The @ifc-lite/solar package computes solar position, sunrise and sunset times, and 3D sun-path geometry (day arcs, hourly analemmas, and a dome graticule) from just a date and a site latitude/longitude.
Accuracy is about 0.01 degrees for the years 1900 to 2100, using the NOAA algorithms (truncated Meeus/VSOP).
Conventions¶
- Azimuth - degrees clockwise from true north, 0 to 360
- Altitude - degrees above the horizon (negative when the sun is below it)
- Dates - a
Dateis treated as an absolute UTC instant; latitude is north-positive, longitude east-positive, both plain numbers (there is no location object type) - Geometry - all path generators return unit direction vectors in ENU (east, north, up) as
{ e, n, u }; a renderer scales them by a dome radius and adds the site origin
Quick Start¶
Sun Position¶
import { sunPosition } from '@ifc-lite/solar';
// sunPosition(date: Date, latitude: number, longitude: number): SunPosition
const pos = sunPosition(new Date('2024-06-21T12:00:00Z'), 51.4769, -0.0005);
pos.azimuth; // degrees clockwise from true north (0-360)
pos.altitude; // degrees above the horizon
pos.declination; // solar declination in degrees
pos.equationOfTime; // apparent minus mean solar time, in minutes
Sunrise and Sunset¶
import { sunTimes } from '@ifc-lite/solar';
// sunTimes(date: Date, latitude: number, longitude: number): SunTimes
const times = sunTimes(new Date('2024-06-21T12:00:00Z'), 51.4769, -0.0005);
times.sunrise; // Date | null (null during polar night)
times.sunset; // Date | null (null during midnight sun)
times.solarNoon; // Date, always defined
times.alwaysUp; // true if the sun never sets that UTC day
times.alwaysDown; // true if it never rises
Times are computed for the UTC calendar day containing date, with the standard refraction-corrected zenith of 90.833 degrees.
Worked Example: Sun Position and Sun-Path Geometry¶
import {
sunPosition,
dayPath,
analemmaPaths,
domeGraticule,
azimuthAltitudeToEnu,
} from '@ifc-lite/solar';
const lat = 51.4769; // degrees north
const lon = -0.0005; // degrees east
const date = new Date('2024-06-21T12:00:00Z');
// 1. Where is the sun right now?
const { azimuth, altitude } = sunPosition(date, lat, lon);
// 2. Turn the angles into a renderable direction
const dir = azimuthAltitudeToEnu(azimuth, altitude); // { e, n, u } unit vector
// worldPos = siteOrigin + dir * domeRadius
// 3. The day arc: an ordered morning-to-evening polyline of SunSample
const arc = dayPath(date, lat, lon, {
stepMinutes: 10, // default 10
aboveHorizonOnly: true // default true: drop below-horizon samples
});
// each sample: { time, azimuth, altitude, dir: { e, n, u }, aboveHorizon, ... }
// 4. Hourly analemmas for a whole year (note: first argument is a YEAR, not a Date)
const analemmas = analemmaPaths(2024, lat, lon, { dayStep: 5 });
// one AnalemmaPath { hour, samples } per clock hour with above-horizon samples
// 5. A static dome reference grid (site and date independent)
const grid = domeGraticule({ altitudeStep: 15, azimuthStep: 30, resolution: 5 });
// grid.altitudeRings: { altitude, ring: Enu[] }[]
// grid.azimuthSpokes: { azimuth, arc: Enu[] }[]
// grid.cardinals: { label, dir: Enu }[] (N, NE, E, ...)
All geometry functions return plain data (ENU unit vectors), not renderer buffers, so the package works with any 3D engine.
API Summary¶
| Export | Description |
|---|---|
sunPosition(date, latitude, longitude) |
Azimuth, altitude, declination, equation of time |
sunPositionFromGeometry(date, lat, lon, declination, equationOfTime) |
Fast variant for per-day loops that already computed geometry |
solarGeometry(date) |
Date-only declination and equation of time |
toJulianDay(date) |
Julian day number |
sunTimes(date, latitude, longitude) |
Sunrise, sunset, solar noon, polar flags |
azimuthAltitudeToEnu(azimuthDeg, altitudeDeg) |
Angles to ENU unit vector |
dayPath(date, latitude, longitude, options?) |
Sun arc for one day as SunSample[] |
analemmaPaths(year, latitude, longitude, options?) |
Hourly figure-eight paths for a year |
domeGraticule(options?) |
Altitude rings, azimuth spokes, compass cardinals |
Key types: SunPosition, SunTimes, Enu, SunSample, DayPathOptions, AnalemmaPath, AnalemmaOptions, Graticule, GraticuleOptions.
Viewer Integration¶
The IFClite viewer builds a full solar study on top of this package:
- Sun & Sky panel - Pick a date and time; the viewer computes the sun with
sunPositionandsunTimesfor the model's georeferenced site - Sun-path dome - A "Dome" toggle overlays the day arc, hourly analemmas, graticule, compass cardinals, and a live sun marker on the model (in the Cesium map view the ENU vectors are pinned to the site through an east-north-up frame at the model origin)
- Shadow study - The computed sun direction drives scene lighting and shadows for a studied instant
The site location comes from the model's georeferencing, so a correctly georeferenced IFC gets a physically accurate sun with no extra setup.
See the package README for the full API reference.