Гелиостат для управления зеркалом

я так понимаю, с этим у местных проблема, я помогу. вот функция на сишарп, она несложная, переписать на любой язык легко и недолго.


/// <summary>
        /// Вычисляет текущее положение Солнца относительно горизонта для определения начала и конца темного времени суток.
        /// для вычисления используются координаты текущего положения устройства, заданные в классе GlobalVars
        /// </summary>
        /// <param name="azimuthdegrees"></param>
        /// <param name="altitudedegrees"></param>
        private static void CalculateSunPosition(out double azimuthdegrees, out double altitudedegrees)
        {
            DateTime dateTime = DateTime.Now;
            double Deg2Rad = 0.01745329251994329576923690768489;
            double Rad2Deg = 1 / Deg2Rad;
            // Convert to UTC
            dateTime = dateTime.ToUniversalTime();
            // Number of days from J2000.0.
            double julianDate = 367 * dateTime.Year - (int)((7.0 / 4.0) * (dateTime.Year + (int)((dateTime.Month + 9.0) / 12.0)))
                      + (int)((275.0 * dateTime.Month) / 9.0) + dateTime.Day - 730531.5;
            double julianCenturies = julianDate / 36525.0;
            // Sidereal Time
            double siderealTimeHours = 6.6974 + 2400.0513 * julianCenturies;
            double siderealTimeUT = siderealTimeHours + (366.2422 / 365.2422) * dateTime.TimeOfDay.TotalHours;
            double siderealTime = siderealTimeUT * 15 + StartPage.CurrentDeviceSettings.Longitude;
            // Refine to number of days (fractional) to specific time.
            julianDate += dateTime.TimeOfDay.TotalHours / 24.0;
            julianCenturies = julianDate / 36525.0;
            // Solar Coordinates
            double meanLongitude = CorrectAngle(Deg2Rad * (280.466 + 36000.77 * julianCenturies));
            double meanAnomaly = CorrectAngle(Deg2Rad * (357.529 + 35999.05 * julianCenturies));
            double equationOfCenter = Deg2Rad * ((1.915 - 0.005 * julianCenturies) * Math.Sin(meanAnomaly) + 0.02 * Math.Sin(2 * meanAnomaly));
            double elipticalLongitude = CorrectAngle(meanLongitude + equationOfCenter);
            double obliquity = (23.439 - 0.013 * julianCenturies) * Deg2Rad;
            // Right Ascension
            double rightAscension = Math.Atan2(Math.Cos(obliquity) * Math.Sin(elipticalLongitude), Math.Cos(elipticalLongitude));
            double declination = Math.Asin(Math.Sin(rightAscension) * Math.Sin(obliquity));
            // Horizontal Coordinates
            double hourAngle = CorrectAngle(siderealTime * Deg2Rad) - rightAscension;
            if (hourAngle > Math.PI)
            {
                hourAngle -= 2 * Math.PI;
            }
            altitudedegrees = Math.Asin(Math.Sin(StartPage.CurrentDeviceSettings.Latitude * Deg2Rad) * Math.Sin(declination) + Math.Cos(StartPage.CurrentDeviceSettings.Latitude * Deg2Rad) * Math.Cos(declination) * Math.Cos(hourAngle));
            // Nominator and denominator for calculating Azimuth
            // angle. Needed to test which quadrant the angle is in.
            double aziNom = -Math.Sin(hourAngle);
            double aziDenom = Math.Tan(declination) * Math.Cos(StartPage.CurrentDeviceSettings.Latitude * Deg2Rad) - Math.Sin(StartPage.CurrentDeviceSettings.Latitude * Deg2Rad) * Math.Cos(hourAngle);
            azimuthdegrees = Math.Atan(aziNom / aziDenom);
            if (aziDenom < 0) // In 2nd or 3rd quadrant
            {
                azimuthdegrees += Math.PI;
            }
            else if (aziNom < 0) // In 4th quadrant
            {
                azimuthdegrees += 2 * Math.PI;
            }
            azimuthdegrees *= Rad2Deg;
            altitudedegrees *= Rad2Deg;
        }

/// <summary>
        /// Определяет, в какой четверти координатной плоскости находится угол
        /// </summary>
        /// <param name="angleInRadians"></param>
        /// <returns></returns>
        private static double CorrectAngle(double angleInRadians)
        {
            if (angleInRadians < 0)
            {
                return 2 * Math.PI - (Math.Abs(angleInRadians) % (2 * Math.PI));
            }
            if (angleInRadians > 2 * Math.PI)
            {
                return angleInRadians % (2 * Math.PI);
            }
            return angleInRadians;
        }
```