Last active
September 17, 2023 13:45
-
-
Save ijrussell/e1417ecdf3d2b263abac32fa677c3b89 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on original at https://gist.github.com/houstonhaynes/fcc26d0265d1572fbdb093af88da926a | |
#r "nuget: CoordinateSharp" | |
open System | |
open CoordinateSharp | |
let find_Closest_TimeUnit = | |
let el = EagerLoad(EagerLoadType.Celestial) | |
el.Extensions <- EagerLoad_Extensions(EagerLoad_ExtensionsType.Solar_Cycle) | |
fun addTimeFn rangeStart rangeEnd (c : Coordinate) azimuth adjustNegatively -> | |
let start = if adjustNegatively then -rangeEnd else rangeStart | |
[start..rangeEnd] | |
|> List.map (fun x -> | |
let newTime = addTimeFn (float x) | |
let nc = Coordinate(c.Latitude.ToDouble(), c.Longitude.ToDouble(), newTime, el) | |
nc.Offset <- c.Offset | |
(Math.Abs(nc.CelestialInfo.SunAzimuth - azimuth), x) | |
) | |
|> List.minBy (fun (diff, _) -> diff) | |
|> fun (_, closestTime) -> addTimeFn (float closestTime) | |
let get_Time_At_Solar_Azimuth azimuth (c : Coordinate) = | |
let hour = find_Closest_TimeUnit (c.GeoDate.AddHours) 0 23 c azimuth false | |
let minute = find_Closest_TimeUnit (hour.AddMinutes) 0 59 c azimuth true | |
let second = find_Closest_TimeUnit (minute.AddSeconds) 0 59 c azimuth true | |
second | |
let main () = | |
let lateAzimuth = 202.00 | |
let earlyAzimuth = 158.00 | |
let lat = 35.0 | |
let lon = -82.5 | |
let offset = -5.0 | |
let d = DateTime(2024, 1, 1) | |
let c = Coordinate(lat, lon, d) | |
c.Offset <- offset | |
let timeAtEarlyAzimuth = get_Time_At_Solar_Azimuth earlyAzimuth c | |
let timeAtLateAzimuth = get_Time_At_Solar_Azimuth lateAzimuth c | |
printfn "Time at Sunrise: %A" c.CelestialInfo.SunRise | |
printfn "Time at early azimuth: %A" timeAtEarlyAzimuth | |
printfn "Solar noon: %A" c.CelestialInfo.SolarNoon | |
printfn "Time at late azimuth: %A" timeAtLateAzimuth | |
printfn "Time at Sunset: %A" c.CelestialInfo.SunSet | |
if c.CelestialInfo.SolarNoon.HasValue then | |
let ts = timeAtLateAzimuth - c.CelestialInfo.SolarNoon.Value | |
printfn "Time range from Solar noon: %d:%d" ts.Hours (abs ts.Minutes) | |
let c = Coordinate(lat, lon, timeAtEarlyAzimuth) | |
c.Offset <- offset | |
printfn "Early azimuth at time verification: %A" c.CelestialInfo.SunAzimuth | |
main () | |
(* | |
Time at Sunrise: 1/1/2024 7:39:08 AM | |
Time at early azimuth: 1/1/2024 11:11:47 AM | |
Solar noon: 1/1/2024 12:34:29 PM | |
Time at late azimuth: 1/1/2024 1:59:09 PM | |
Time at Sunset: 1/1/2024 5:29:49 PM | |
Time range from Solar noon: 1:24 | |
Early azimuth at time verification: 157.9994881 | |
*) | |
(* use http://sunfollower.net to verify these dat/time points *) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment