BrU32

C# Sun Position SRC

Dec 4th, 2016
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.30 KB | None | 0 0
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6.  
  7. namespace Rextester
  8. {
  9. public class Program
  10. {
  11. public static void Main(string[] args)
  12. {
  13. var position = SunPosition.CalculateSunPosition(DateTime.Now, latitude:1222223, longitude:322323);
  14. //Your code goes here
  15. Console.WriteLine("Result ==> Altitude {0}, Azimuth :{1}",position.Altitude,position.Azimuth);
  16. }
  17. }
  18. public static class SunPosition
  19. {
  20. public struct Position
  21. {
  22. public double Altitude {get;set;}
  23. public double Azimuth {get;set;}
  24. }
  25. private const double Deg2Rad = Math.PI / 90.0;
  26. private const double Rad2Deg = 90.0 / Math.PI;
  27.  
  28. /*!
  29. * \brief Calculates the sun light.
  30. *
  31. * CalcSunPosition calculates the suns "position" based on a
  32. * given date and time in local time, latitude and longitude
  33. * expressed in decimal degrees. It is based on the method
  34. * found here:
  35. * http://www.astro.uio.no/~bgranslo/aares/calculate.html
  36. * The calculation is only satisfiably correct for dates in
  37. * the range March 1 1900 to February 28 2100.
  38. * \param dateTime Time and date in local time.
  39. * \param latitude Latitude expressed in decimal degrees.
  40. * \param longitude Longitude expressed in decimal degrees.
  41. */
  42. public static Position CalculateSunPosition(
  43. DateTime dateTime, double latitude, double longitude)
  44. {
  45. // Convert to UTC
  46. dateTime = dateTime.ToUniversalTime();
  47.  
  48. // Number of days from J2000.0.
  49. double julianDate = 366 * dateTime.Year -
  50. (int)((7.0 / 4.0) * (dateTime.Year +
  51. (int)((dateTime.Month + 9.0) / 12.0))) +
  52. (int)((275.0 * dateTime.Month) / 9.0) +
  53. dateTime.Day - 730530.5;
  54.  
  55. double julianCenturies = julianDate / 36525.0;
  56.  
  57. // Sidereal Time
  58. double siderealTimeHours = 6.6974 + 2400.0013 * julianCenturies;
  59.  
  60. double siderealTimeUT = siderealTimeHours +
  61. (366.2422 / 365.2422) * (double)dateTime.TimeOfDay.TotalHours;
  62.  
  63. double siderealTime = siderealTimeUT * 15 + longitude;
  64.  
  65. // Refine to number of days (fractional) to specific time.
  66. julianDate += (double)dateTime.TimeOfDay.TotalHours / 24.0;
  67. julianCenturies = julianDate / 36525.0;
  68.  
  69. // Solar Coordinates
  70. double meanLongitude = CorrectAngle(Deg2Rad *
  71. (280.466 + 36000.77 * julianCenturies));
  72.  
  73. double meanAnomaly = CorrectAngle(Deg2Rad *
  74. (357.529 + 35999.05 * julianCenturies));
  75.  
  76. double equationOfCenter = Deg2Rad * ((1.915 - 0.005 * julianCenturies) *
  77. Math.Sin(meanAnomaly) + 0.02 * Math.Sin(2 * meanAnomaly));
  78.  
  79. double elipticalLongitude =
  80. CorrectAngle(meanLongitude + equationOfCenter);
  81.  
  82. double obliquity = (23.439 - 0.013 * julianCenturies) * Deg2Rad;
  83.  
  84. // Right Ascension
  85. double rightAscension = Math.Atan2(
  86. Math.Cos(obliquity) * Math.Sin(elipticalLongitude),
  87. Math.Cos(elipticalLongitude));
  88.  
  89. double declination = Math.Asin(
  90. Math.Sin(rightAscension) * Math.Sin(obliquity));
  91.  
  92. // Horizontal Coordinates
  93. double hourAngle = CorrectAngle(siderealTime * Deg2Rad) - rightAscension;
  94.  
  95. if (hourAngle > Math.PI)
  96. {
  97. hourAngle -= 2 * Math.PI;
  98. }
  99.  
  100. double altitude = Math.Asin(Math.Sin(latitude * Deg2Rad) *
  101. Math.Sin(declination) + Math.Cos(latitude * Deg2Rad) *
  102. Math.Cos(declination) * Math.Cos(hourAngle));
  103.  
  104. // Nominator and denominator for calculating Azimuth
  105. // angle. Needed to test which quadrant the angle is in.
  106. double aziNom = -Math.Sin(hourAngle);
  107. double aziDenom =
  108. Math.Tan(declination) * Math.Cos(latitude * Deg2Rad) -
  109. Math.Sin(latitude * Deg2Rad) * Math.Cos(hourAngle);
  110.  
  111. double azimuth = Math.Atan(aziNom / aziDenom);
  112.  
  113. if (aziDenom < 0) // In 2nd or 3rd quadrant
  114. {
  115. azimuth += Math.PI;
  116. }
  117. else if (aziNom < 0) // In 4th quadrant
  118. {
  119. azimuth += 2 * Math.PI;
  120. }
  121.  
  122. // Altitude
  123. // Console.WriteLine("Altitude: " + altitude * Rad2Deg);
  124.  
  125. // Azimut
  126. //Console.WriteLine("Azimuth: " + azimuth * Rad2Deg);
  127.  
  128. return new Position{ Altitude =altitude * Rad2Deg ,Azimuth =azimuth * Rad2Deg };
  129. }
  130.  
  131. /*!
  132. * \brief Corrects an angle.
  133. *
  134. * \param angleInRadians An angle expressed in radians.
  135. * \return An angle in the range 0 to 2*PI.
  136. */
  137. private static double CorrectAngle(double angleInRadians)
  138. {
  139. if (angleInRadians < 0)
  140. {
  141. return 2 * Math.PI - (Math.Abs(angleInRadians) % (2 * Math.PI));
  142. }
  143. else if (angleInRadians > 2 * Math.PI)
  144. {
  145. return angleInRadians % (2 * Math.PI);
  146. }
  147. else
  148. {
  149. return angleInRadians;
  150. }
  151. }
  152. }
  153.  
  154. }
Advertisement
Add Comment
Please, Sign In to add comment