3

I want to draw a Sun in a 3d scene, so I figured the easiest way would be to calculate the latitude and longitude of the point perpendicular to Sun position and then just move it "up".

As a starting point, I want to calculate it's equatorial coordinates: declination and right ascension.

I followed instructions from this page, also cross-referencing with this one

Here's my code (in Swift):

import Foundation

class Astronomy {

  static func julianDays(since: Date) -> Double {
    return since.timeIntervalSince1970 / 86400 + 2440587.5
  }

  static func daysSinceJ2000(for date: Date) -> Double {
    return julianDays(since: date) - 2451545
  }

  static func sunAxialTilt(for daysSinceJ200: Double) -> Double {
    return 23.4393 - 3.563e-7 * daysSinceJ200
  }

  static func sunEquatorialPosition(on date: Date) -> (declination: Double, RA: Double, distance: Double) {
    let daysSinceGreenwichNoon = daysSinceJ2000(for: date)
    var meanLongitude = 280.460 + 0.9856474*daysSinceGreenwichNoon
    var meanAnomaly = 357.528 + 0.9856003*daysSinceGreenwichNoon
    meanLongitude = meanLongitude.rangedUpTo360
    meanAnomaly = meanAnomaly.rangedUpTo360
    let eclipticLongitude = meanLongitude + 1.915*sin(meanAnomaly.radians) + 0.020*sin(2*meanAnomaly.radians)

    let distanceToEarth = 1.00014 - 0.01671*cos(meanAnomaly.radians) - 0.00014*cos(2*meanAnomaly.radians)

    let axialTilt = sunAxialTilt(for: daysSinceGreenwichNoon)
    let rightAscension = atan2(cos(axialTilt.radians)*sin(eclipticLongitude.radians), cos(eclipticLongitude.radians))
    let declination = asin(sin(axialTilt.radians)*sin(eclipticLongitude.radians))

    return (declination: declination.degrees, RA: rightAscension.degrees, distance: distanceToEarth)
  }
}

extension Double {
  var radians: Double {
    return self * .pi / 180
  }

  var degrees: Double {
    return self  * 180 / .pi
  }

  var rangedUpTo360: Double {
    let multiples = (self/360).rounded(.down)
    return self - 360*multiples
  }
}

However, it does not seem to be working correctly. As of the time I write this article, the result is declination -16.98772292697088, RA -44.80674952684117. Compared with https://theskylive.com/sun-info the declination is about right (-17° 03’ 38”), but right ascension is way off: 20h 59m 43s, which is 314.93 degrees according to this site

What went wrong?

Edit: As it turned out nothing was wrong, I can get to the second part: calculating the geographical point. (the title suggests it after all)

AFAIK for latitude, I can use declination as is and for longitude, I need to calculate Greenwich Hour Angle(GHA)

After examining several articles, I found these equations:

SHA[°] = 360 – 15 · RA[h] 
GHAAries[°] = 15 · GST[h] 
GHA = SHA + GHAAries 

For my case, I suppose I may use RA as is, without multiplying its hour component by 15. What keeps me a bit puzzled is GST:

  1. May I use Greenwich Mean Sidereal Time instead if I don't need the calculations to be super precise?
  2. Is there any "GST for dummies"? All the calculations I found rely on some floating second offset, I found this table but have no idea how to use it.
bitemybyte
  • 163
  • 5
  • 1
    I don't think anything went wrong ... 314.93 - -44.807 is roughly 360 degrees ... meaning it's the same right ascension. The reason for slight inaccuracy likely has things to do with floating-point integer accuracy and the fact that the Sun's right ascension is very difficult to very accurately measure in practice. – Tosic Feb 01 '19 at 22:43
  • I'm voting to close this question as off-topic because it's about coding rather than astronomy. – Chappo Hasn't Forgotten Feb 02 '19 at 06:57
  • @Tosic ahh I see, so I have to add 360 if my resulting value would be < 0, thank you very much! – bitemybyte Feb 02 '19 at 08:52
  • 2
    @Chappo I disagree, it is not about how to code something, but about interpreting the results, as the code is essentially math – bitemybyte Feb 02 '19 at 08:52
  • @Chappo I also disagree with the close; a large number of formulas in astronomy require renormalization into the range 0..360 (or 0..2PI in radians). Some texts are good at telling you that you need to do this, some aren't. So a question that illustrates the need to renormalize quantities such as RA or GST or planetary longitudes to get the correct answer is useful IMHO. – astrosnapper Feb 05 '19 at 01:17
  • @ethamine Not necessarily very "dummies"-like but here is an explanation of Sidereal Time. GMST is a function of UT1, which is really a rotation angle of the Earth, rather than a time. You could add the 'UT1-UTC' value from you link to your UTC clock time in your code but the difference is kept <0.9s by leapseconds. If you add your longitude (East positive) to GMST, normalize, then subtract the RA of the Sun, you get local hour angle. Leave out the longitude and you have Greenwich Hour Angle (Hour Angle at 0deg longitude) – astrosnapper Feb 05 '19 at 01:37
  • @astrosnapper thank you, I think I'm beginning to understand. I found this question very useful. I think I might have spotted an error in my code. For calculating Julian days, I take a date, but in my code, this date is in the local timezone. Am I correct in assuming that all the dates I use, considering the goal, should be on Greenwich timezone, UTC+0? – bitemybyte Feb 08 '19 at 20:44
  • Yes, you should be using UTC internally in your code, only converting to and from a local timezone at input (if applicable) and for display at the end. The other time you will need if you are calculating anything to do with the positions of e.g. Sun/Earth is a Dynamical Time either TDB or TT (the steps in UTC caused by leap seconds make it unsuitable). TT is easier and good enough for almost all purposes; TT-UTC is currently 69.184s made up of TT-TAI=32.184s (fixed forever) and TAI-UTC=37s (currently; changes with leapseconds, see ftp://maia.usno.navy.mil/ser7/tai-utc.dat for past values) – astrosnapper Feb 08 '19 at 21:42

2 Answers2

2

If we draw a circle and draw a 315 degree angle on that circle, in the counter clockwise direction, we would roughly get the same point as when we draw an angle of 44.8 degrees in the opposite direction (the equivalent of drawing -44.8 in the same direction) because 315+45=360. There therefore does not seem to be an error in your results... Visually the two angles are the same. As for the slight inaccuracy, it may be due to floating point precision errors or measurement errors.
If you want positive right ascension, all you need to do is add 360 if it is negative. Before doing that (this is general advice, it may not be important to your code), you ought to subtract the decimal part, get the remainder on dividing by 360, and re-add the decimal part.
Edit: The difference between GST and GMST is called the equation of time (for Grinich), and it does not grow beyond 16 minutes, so I think you can use it for estimates, but then there would be no point of rounding your results to the tenth decimal or so. I honestly don't know if there is a "GST for dummies" (normally I wouldn't post an incomplete answer, but the question was edited), but using GMST should suffice if the 16 minute error margin is acceptable.

Tosic
  • 1,681
  • 11
  • 19
  • Could you please elaborate, why is it advisable to perform calculations with the decimal part in such a way? – bitemybyte Feb 02 '19 at 15:06
  • I am not familiar with swift, but in C++ one cannot take the modulo of a floating point integer, so i recommended that course of action. – Tosic Feb 02 '19 at 16:09
  • Ahh I see, thank you for clarifications. Swift allows taking modulo of a float number. Could you please have a look at my updated question? – bitemybyte Feb 02 '19 at 16:21
  • 1
    Edited. Sorry it took so long, this is the best answer I can give. Out of topic, but I highly recommend posting a new question next time instead of updating your old one to include a new topic, as it will get much more attention that way. – Tosic Feb 03 '19 at 16:06
  • 2
    thank you very much. I thought of creating a separate question, but as the title said "geographical point" and not "right ascension" the thread would be incomplete otherwise – bitemybyte Feb 04 '19 at 10:45
0

For any who might be looking for the same sort of thing, my own solution to my question does roughly what this question is asking, though the calculations are shown in TypeScript.

Michael Bonnet
  • 547
  • 1
  • 9