private static double Interpolate( SolarTimes solarTimes, double dayValue, double nightValue, TimeSpan transitionDuration, double transitionOffset, DateTimeOffset instant) { var sunriseStart = GetSunriseStart(solarTimes.Sunrise, transitionDuration, transitionOffset); var sunriseEnd = GetSunriseEnd(solarTimes.Sunrise, transitionDuration, transitionOffset); var sunsetStart = GetSunsetStart(solarTimes.Sunset, transitionDuration, transitionOffset); var sunsetEnd = GetSunsetEnd(solarTimes.Sunset, transitionDuration, transitionOffset); // Sunrise transition var prevSunriseStart = sunriseStart.PreviousBefore(instant); var nextSunriseEnd = sunriseEnd.NextAfter(instant); var isDuringSunrise = (nextSunriseEnd - prevSunriseStart).Duration() <= transitionDuration; if (isDuringSunrise) { var progress = (instant - prevSunriseStart) / transitionDuration; return(dayValue + (nightValue - dayValue) * Math.Cos(progress * Math.PI / 2)); } // Sunset transition var prevSunsetStart = sunsetStart.PreviousBefore(instant); var nextSunsetEnd = sunsetEnd.NextAfter(instant); var isDuringSunset = (nextSunsetEnd - prevSunsetStart).Duration() <= transitionDuration; if (isDuringSunset) { var progress = (instant - prevSunsetStart) / transitionDuration; return(dayValue + (nightValue - dayValue) * Math.Sin(progress * Math.PI / 2)); } // Day time if (nextSunsetEnd < nextSunriseEnd) { return(dayValue); } // Night time return(nightValue); }