MeeusJs icon indicating copy to clipboard operation
MeeusJs copied to clipboard

Calculating when the sun is at a specific angle?

Open mennyg opened this issue 5 years ago • 1 comments

Need this to calculate certain times even before sunrise. When is the sun X degrees below/above the horizon? Suncalc has a function called addtimes() that takes an angle as a parameter and returns a time, but suncalc is returning very inaccurate times, and I want to use MeeusJs

mennyg avatar Aug 27 '20 09:08 mennyg

I am using this function to calculate sun position at given time:

function suncalcMeeus(myDateJS, lat, lon, height) {
// gets sun position and times 
  var jdo = new A.JulianDay(myDateJS); 
  var coord = A.EclCoord.fromWgs84(lat, lon, height);

  // gets the position of the sun
  var tp = A.Solar.topocentricPosition(jdo, coord, true);
  var altRad = tp.hz.alt;
  var altDeg = altRad * 180 / Math.PI;
  var azRad = tp.hz.az;
  var azDeg = azRad * 180 / Math.PI;
  var distKm =  tp.delta; // debug

  if (azRad < 0) {
     azRad = Math.PI + azRad;
     azDeg = 180.0 + azDeg;
  }
  // gets the rise, transit and set time of the sun
  var times = A.Solar.times(jdo, coord);

  return {
    sunAzimuthRad : azRad,
    sunAltitudeRad : altRad,
    sunAzimuthDegrees : azDeg,
    sunAltitudeDegrees : altDeg,
    rise : A.Coord.secondsToHMSStr(times.rise),
    riseJS : new Date(myDateJS.getFullYear() + "-" + (myDateJS.getMonth()+1) + "-" + myDateJS.getDate() + " "  + A.Coord.secondsToHMSStr(times.rise)),
    transit : A.Coord.secondsToHMSStr(times.transit) ,
    transitJS : new Date(myDateJS.getFullYear() + "-" + (myDateJS.getMonth()+1) + "-" + myDateJS.getDate() + " "  + A.Coord.secondsToHMSStr(times.transit)),
    set: A.Coord.secondsToHMSStr(times.set),
    setJS : new Date(myDateJS.getFullYear() + "-" + (myDateJS.getMonth()+1) + "-" + myDateJS.getDate() + " "  + A.Coord.secondsToHMSStr(times.set)),
  }
}

You can iterate throuogh myDateJS while monitoring for elevation value, for example:

function elevThreshold(THRESHOLD, d) { 
 var tempResults = []; 
 baseDateJS = new Date(d)
 for (var m=0; m < 1440; m++) { 
   myDateJS = new Date(baseDateJS.getTime() + m * 60000);
   res = suncalcMeeus(myDateJS, 42,12,0);
   if (res.sunAltitudeDegrees <= THRESHOLD) {
     tempResults.push("Time: "+ myDateJS.getHours() + ":" + myDateJS.getMinutes() + ", Elevation: "+ res.sunAltitudeDegrees)
   }
 }
 return { all: tempResults, first: tempResults[0], last: tempResults[tempResults.length-1]} 
}

Call:

elevThreshold(-10, "2023-03-01 12:00:00Z");

Result:

first: "Time: 18:55, Elevation: -10.119625318268696" ​ last: "Time: 5:53, Elevation: -10.105459335822681"

jumpjack avatar Mar 01 '23 09:03 jumpjack