mirror of
https://github.com/acamarata/pray-calc.git
synced 2026-07-01 03:14:28 +00:00
63 lines
No EOL
2.2 KiB
JavaScript
63 lines
No EOL
2.2 KiB
JavaScript
// getAngles.js
|
||
'use strict';
|
||
|
||
const PI = Math.PI;
|
||
|
||
/**
|
||
* Calculate dynamic Fajr and Isha depression angles based on the current date (season)
|
||
* plus refraction and elevation adjustments.
|
||
*
|
||
* @param {number} [elevation=0] Observer elevation in meters.
|
||
* @param {number} [pressure=1013.25] Atmospheric pressure in mbar.
|
||
* @param {number} [temperature=15] Temperature in °C.
|
||
* @returns {{ fajrAngle: number, ishaAngle: number }} Depression angles in degrees.
|
||
*/
|
||
function getAngles(elevation = 0, pressure = 1013.25, temperature = 15) {
|
||
// 1) Compute day of year (1–365/366)
|
||
const today = new Date();
|
||
const start = Date.UTC(today.getFullYear(), 0, 0);
|
||
const diffMs = today - start;
|
||
const dayOfYear = Math.floor(diffMs / 86400000);
|
||
|
||
// 2) Approximate solar declination δ (radians):
|
||
// δ = 23.44° * sin(2π * (day + 284) / 365)
|
||
const declRad = (23.44 * Math.sin(2 * PI * (dayOfYear + 284) / 365)) * (PI / 180);
|
||
|
||
// 3) Seasonal factor (−1 to +1)
|
||
const seasonalFactor = Math.sin(declRad);
|
||
|
||
// 4) Base and amplitude for twilight angle (±2° variation)
|
||
const baseAngle = 18.0;
|
||
const amplitude = 2.0;
|
||
const seasonalAngle = baseAngle + amplitude * seasonalFactor;
|
||
|
||
// 5) Refraction correction at horizon (altitude = 0)
|
||
const refraction = calculateAtmosphericRefraction(0, pressure, temperature);
|
||
|
||
// 6) Elevation adjustment (0.1° per 1000 m)
|
||
const elevationAdjustment = (elevation / 1000) * 0.1;
|
||
|
||
// 7) Final angles
|
||
const fajrAngle = seasonalAngle + refraction + elevationAdjustment;
|
||
const ishaAngle = seasonalAngle - refraction - elevationAdjustment;
|
||
|
||
return { fajrAngle, ishaAngle };
|
||
}
|
||
|
||
/**
|
||
* Compute atmospheric refraction correction at a given altitude.
|
||
*
|
||
* @param {number} altitude Solar altitude in degrees.
|
||
* @param {number} pressure Atmospheric pressure in mbar.
|
||
* @param {number} temperature Temperature in °C.
|
||
* @returns {number} Refraction correction in degrees.
|
||
*/
|
||
function calculateAtmosphericRefraction(altitude, pressure = 1013.25, temperature = 10) {
|
||
const altRad = altitude * PI / 180;
|
||
let R = 1.0 / Math.tan(altRad + 7.31 / (altRad + 0.077));
|
||
R = R / 60; // arcminutes → degrees
|
||
R = (pressure / 1010) * (283 / (273 + temperature)) * R;
|
||
return R;
|
||
}
|
||
|
||
module.exports = { getAngles }; |