private void TrackTo(Sun sun) { _isDark = sun.dark; if (System.Math.Abs(sun.azimuth - _horizontalActuator.CurrentAngle) > POSITIONINTERVAL) { _horizontalActuator.MoveTo(sun.azimuth); ArrayAzimuth = _horizontalActuator.CurrentAngle; } if (DualAxis) { var invertedAngle = 90 - sun.elevation; if (System.Math.Abs(invertedAngle - _verticalActuator.CurrentAngle) > POSITIONINTERVAL) { _verticalActuator.MoveTo(invertedAngle); ArrayElevation = 90 - _verticalActuator.CurrentAngle; } } }
/// <summary> /// calculate solar position for the entered date, time and /// location. Results are reported in azimuth and elevation /// (in degrees) and cosine of solar zenith angle. /// </summary> /// <param name="latitude"></param> /// <param name="longitude"></param> /// <param name="dateTime"></param> public static Sun CalcSun(double latitude, double longitude, DateTime dateTime) { var result = new Sun(); if ((latitude >= -90) && (latitude < -89.8)) { //"All latitudes between 89.8 and 90 S\n will be set to -89.8." latitude = -89.8; } if ((latitude <= 90) && (latitude > 89.8)) { //"All latitudes between 89.8 and 90 N\n will be set to 89.8." latitude = 89.8; } var jd = JD(dateTime); var jc = JulianCent(jd); var theta = SunDeclination(jc); double etime = EquationOfTime(jc); var eqTime = etime; var solarDec = theta; // in degrees result.eqTime = (Math.Floor(100*eqTime))/100; result.solarDec = (Math.Floor(100*(solarDec)))/100; var solarTimeFix = (eqTime + 4.0*longitude); var trueSolarTime = dateTime.TimeOfDay.Hours*60 + dateTime.TimeOfDay.Minutes + dateTime.TimeOfDay.Seconds/60 + solarTimeFix; while (trueSolarTime > 1440) { trueSolarTime -= 1440; } var hourAngle = trueSolarTime/4.0 - 180.0; if (hourAngle < -180) { hourAngle += 360.0; } var haRad = DegreeToRadian(hourAngle); var csz = Math.Sin(DegreeToRadian(latitude))*Math.Sin(DegreeToRadian(solarDec)) + Math.Cos(DegreeToRadian(latitude))*Math.Cos(DegreeToRadian(solarDec))*Math.Cos(haRad); if (csz > 1.0) { csz = 1.0; } else if (csz < -1.0) { csz = -1.0; } var zenith = RadianToDegree(Math.Acos(csz)); var azDenom = (Math.Cos(DegreeToRadian(latitude))*Math.Sin(DegreeToRadian(zenith))); double azimuth = 0; if (Math.Abs(azDenom) > 0.001) { var azRad = ((Math.Sin(DegreeToRadian(latitude))*Math.Cos(DegreeToRadian(zenith))) - Math.Sin(DegreeToRadian(solarDec)))/azDenom; if (Math.Abs(azRad) > 1.0) { if (azRad < 0) { azRad = -1.0; } else { azRad = 1.0; } } azimuth = 180.0 - RadianToDegree(Math.Acos(azRad)); if (hourAngle > 0.0) { azimuth = -azimuth; } } else { if (latitude > 0.0) { azimuth = 180.0; } else { azimuth = 0.0; } } if (azimuth < 0.0) { azimuth += 360.0; } double refractionCorrection; var exoatmElevation = 90.0 - zenith; if (exoatmElevation > 85.0) { refractionCorrection = 0.0; } else { var te = Math.Tan(DegreeToRadian(exoatmElevation)); if (exoatmElevation > 5.0) { refractionCorrection = 58.1/te - 0.07/(te*te*te) + 0.000086/(te*te*te*te*te); } else if (exoatmElevation > -0.575) { refractionCorrection = 1735.0 + exoatmElevation*(-518.2 + exoatmElevation*(103.4 + exoatmElevation*(-12.79 + exoatmElevation*0.711))); } else { refractionCorrection = -20.774/te; } refractionCorrection = refractionCorrection/3600.0; } var solarZen = zenith - refractionCorrection; if (solarZen < 108.0) { // astronomical twilight result.azimuth = (Math.Floor(100*azimuth))/100; result.elevation = (Math.Floor(100*(90.0 - solarZen)))/100; if (solarZen < 90.0) { result.coszen = (Math.Floor(10000.0*(Math.Cos(DegreeToRadian(solarZen)))))/10000.0; } else { result.coszen = 0.0; } } else { result.dark = true; } return result; }
/// <summary> /// calculate solar position for the entered date, time and /// location. Results are reported in azimuth and elevation /// (in degrees) and cosine of solar zenith angle. /// </summary> /// <param name="latitude"></param> /// <param name="longitude"></param> /// <param name="dateTime"></param> public static Sun CalcSun(double latitude, double longitude, DateTime dateTime) { var result = new Sun(); if ((latitude >= -90) && (latitude < -89.8)) { //"All latitudes between 89.8 and 90 S\n will be set to -89.8." latitude = -89.8; } if ((latitude <= 90) && (latitude > 89.8)) { //"All latitudes between 89.8 and 90 N\n will be set to 89.8." latitude = 89.8; } var jd = JD(dateTime); var jc = JulianCent(jd); var theta = SunDeclination(jc); double etime = EquationOfTime(jc); var eqTime = etime; var solarDec = theta; // in degrees result.eqTime = (Math.Floor(100 * eqTime)) / 100; result.solarDec = (Math.Floor(100 * (solarDec))) / 100; var solarTimeFix = (eqTime + 4.0 * longitude); var trueSolarTime = dateTime.TimeOfDay.Hours * 60 + dateTime.TimeOfDay.Minutes + dateTime.TimeOfDay.Seconds / 60 + solarTimeFix; while (trueSolarTime > 1440) { trueSolarTime -= 1440; } var hourAngle = trueSolarTime / 4.0 - 180.0; if (hourAngle < -180) { hourAngle += 360.0; } var haRad = DegreeToRadian(hourAngle); var csz = Math.Sin(DegreeToRadian(latitude)) * Math.Sin(DegreeToRadian(solarDec)) + Math.Cos(DegreeToRadian(latitude)) * Math.Cos(DegreeToRadian(solarDec)) * Math.Cos(haRad); if (csz > 1.0) { csz = 1.0; } else if (csz < -1.0) { csz = -1.0; } var zenith = RadianToDegree(Math.Acos(csz)); var azDenom = (Math.Cos(DegreeToRadian(latitude)) * Math.Sin(DegreeToRadian(zenith))); double azimuth = 0; if (Math.Abs(azDenom) > 0.001) { var azRad = ((Math.Sin(DegreeToRadian(latitude)) * Math.Cos(DegreeToRadian(zenith))) - Math.Sin(DegreeToRadian(solarDec))) / azDenom; if (Math.Abs(azRad) > 1.0) { if (azRad < 0) { azRad = -1.0; } else { azRad = 1.0; } } azimuth = 180.0 - RadianToDegree(Math.Acos(azRad)); if (hourAngle > 0.0) { azimuth = -azimuth; } } else { if (latitude > 0.0) { azimuth = 180.0; } else { azimuth = 0.0; } } if (azimuth < 0.0) { azimuth += 360.0; } double refractionCorrection; var exoatmElevation = 90.0 - zenith; if (exoatmElevation > 85.0) { refractionCorrection = 0.0; } else { var te = Math.Tan(DegreeToRadian(exoatmElevation)); if (exoatmElevation > 5.0) { refractionCorrection = 58.1 / te - 0.07 / (te * te * te) + 0.000086 / (te * te * te * te * te); } else if (exoatmElevation > -0.575) { refractionCorrection = 1735.0 + exoatmElevation * (-518.2 + exoatmElevation * (103.4 + exoatmElevation * (-12.79 + exoatmElevation * 0.711))); } else { refractionCorrection = -20.774 / te; } refractionCorrection = refractionCorrection / 3600.0; } var solarZen = zenith - refractionCorrection; if (solarZen < 108.0) { // astronomical twilight result.azimuth = (Math.Floor(100 * azimuth)) / 100; result.elevation = (Math.Floor(100 * (90.0 - solarZen))) / 100; if (solarZen < 90.0) { result.coszen = (Math.Floor(10000.0 * (Math.Cos(DegreeToRadian(solarZen))))) / 10000.0; } else { result.coszen = 0.0; } } else { result.dark = true; } return(result); }