Search code examples
javascriptmathcoordinate-systemsastronomy

Wrong result calculation Hour angle from altitude azimuth


I am making a Javascript program and on of the functions is to convert altitude/azimuth to right-ascension/declination given a time and latitude. My code can find the declination fairly accurately, I checked with Stellarium. I have been using this site to help me with the math.

My program gives me the wrong value for horizontal ascension which I plan on using to find right ascension (I already have a function to find local sidereal time which works). Here is my code for the equation
var ha = asin(-sin(az)*cos(alt) / cos(dec)) * (180 / Math.PI); this code is in Javascript but I defined custom sin/cos/asin functions that take degrees as input and return radians because that is the form my data is in.

The site I use also says that this equation should give the same result
var ha = acos((sin(alt) - sin(lat)*sin(dec)) / (cos(lat) * cos(dec))) * (180 / Math.PI);
but, the two equations give different results and neither are correct according to stellarium. I have checked that all the variables I am putting in are correct and I am almost certain I entered the equation correct. Here is the full code on github. I need help figuring out how to fix this problem.
--Note this can be run with node js with no libraries The result I get is { ra: [ 23, 57, 37.9 ], dec: [ -5, 24, 38.88 ] }
It should be getting { ra: [ 5, 36, 22.6 ], dec: [ -5, 24, 38.88 ] it does not have to be exact, I only really care about the first number of ra (right ascension). It is also formatted in HMS format. The datetime is hardcoded to Febuary 1st 2022 12:00:00 so that is what you should set stellarium to if you are testing this out.

Here is the relevant code

function altazToradec(alt, az, lat, lon, time){
    /*
    right ascension (α)
    declination (δ)
    altitude (a)
    azimuth (A)
    siderial time (ST)
    latitude (φ) (Φ)
    */
    var lst = getLST(time, lon);
    var dec = asin(sin(lat)*sin(alt) + cos(lat)*cos(alt)*cos(az)) * (180 / Math.PI);
    var ha = asin(sin(az)*cos(alt) / cos(dec)) * (180 / Math.PI);//acos((sin(alt) - sin(lat)*sin(dec)) * (sec(lat) * sec(dec))) * (180 / Math.PI);//acos((sin(alt) - sin(lat)*sin(dec)) / (cos(lat)*cos(dec))) * (180 / Math.PI);
    var ra = lst - ha;
    console.log(ha)
    return {
        "ra": ra,
        "dec": dec
    }
}

Here are some more test cases

console.log(altazToradecHms(-34.6825, 63.7814, 40.5853, -105.0844, new Date('February 1, 2022 12:00:00').getTime()))// Ft. Collins Co M42 Orion nebula Feb 1st 2022 12:00 noon
console.log(altazToradecHms(-34.6825, 63.7814, 41.875, -87.624, new Date('January 1, 2022 08:00:00').getTime()))//Chicago M42 Orion nebula Jan 1st 2022 8:00 AM
console.log(altazToradecHms(301.7678, 64.41758, 51.49, -0.14, new Date('February 1, 2020 12:00:00').getTime()))//London Eta Cas Feb 1st 2020 12:00 noon

which returns

{ ra: [ 23, 57, 37.9 ], dec: [ -5, 24, 38.88 ] }
{ ra: [ 19, 4, 59.25 ], dec: [ -6, 16, 33.68 ] }
{ ra: [ 5, 59, 37.02 ], dec: [ -31, 34, 55.6 ] }

instead of

{ ra: [ 5, 36, 22.7], dec: [ -5, 22, 44 ] }
{ ra: [ 5, 36, 22.7 ], dec: [ -5, 22, 40.3 ] }
{ ra: [ 0, 50, 25.7 ], dec: [ 57, 56, 4.7 ] }

Note: I have checked and I also believe the getLST() function works, I have checked it. Thank you - CR.


Solution

  • Give the following a try. Notable changes include:

    • Specified 'GMT+0000' when establishing J2000.0 date, in addition to the date being passed in to altazToradec(). Otherwise, new Date() returns local time.

    • Sourced calculation of 'DEC' and 'HA' from MathWorks.com (look under the "Functions" tab).

    • NOTE: 'HA' and 'RA' are in degrees, not hours. To convert to hours, multiply by (24 hrs / 360 deg), or simply divide by (15 deg / hr).

    • Sourced sample data from StarGazing.net.

    function deg2rad( x ) { return x * Math.PI / 180 };
    function rad2deg( x ) { return x * 180 / Math.PI };
    
    function sinDeg( x ) {
      return Math.sin( deg2rad( x ) );
    }
    
    function cosDeg( x ) {
      return Math.cos( deg2rad( x ) );
    }
    
    function asinDeg( x ) {
      return rad2deg( Math.asin( x ) );
    }
    
    function atan2Deg( y, x ) {
      return rad2deg( Math.atan2( y, x ) );
    }
    
    // getLST copied from https://github.com/Blank2275/AstroCoordsJS/blob/master/index.js
    // and then tweaked.
    
    function getLST(time, lon){
        //time = new Date(time)
        const J2000Date = new Date('January 1, 2000 12:00:00 GMT+0000').getTime();
        const diff = time - J2000Date;
        const d = diff / (1000 * 60 * 60 * 24);
        var hours = time.getUTCHours();
        var minutes = time.getUTCMinutes();
        var seconds = time.getUTCSeconds();
        var ms = time.getUTCSeconds();
        var utc = (hours * (1000 * 60 * 60) + minutes * (1000 * 60) + seconds * 1000 + ms) / (1000 * 60 * 60 * 24) * 360;//(now.getTime() - beginning.getTime()) / (1000 * 60 * 60 * 24) * 360;
        var lst = 100.46 + (0.985647 * d) + lon + utc;
        if(lst > 360){
            while(lst > 360){
                lst -= 360;
            }
        } else if(lst < 0){
            while(lst < 0){
                lst += 360;
            }
        }
        return lst;
    }
    
    // Equations sourced from https://www.mathworks.com/matlabcentral/fileexchange/24581-convert-azimuth-and-elevation-to-right-ascension-and-declination
    
    function altazToradec( alt, az, lat, lon, time ){
        /*
        right ascension (α)
        declination (δ)
        altitude (a)
        azimuth (A)
        siderial time (ST)
        latitude (φ) (Φ)
        */
        var lst = getLST( time, lon );
        var dec = asinDeg( sinDeg( alt ) * sinDeg( lat ) + cosDeg( alt ) * cosDeg( lat ) * cosDeg( az ) );
        var ha = atan2Deg(
          -sinDeg( az ) * cosDeg( alt ) / cosDeg( dec ),
          ( sinDeg( alt ) - sinDeg( dec ) * sinDeg( lat ) ) / ( cosDeg( dec ) * cosDeg( lat ) )
        );
        var ra = ( lst - ha ) % 360;
    
        return {
            "ha": ha,
            "ra": ra,
            "dec": dec
        }
    }
    
    // See example from http://www.stargazing.net/kepler/altaz.html#twig04
    
    console.log( 'Input:  ALT = 49.169122, AZ = 269.14634, LAT = 52.5, LON = 0, Date = 2310 UT on 10th Aug 1998' );
    console.log( 'Expected Output:  HA = 54.382617, DEC = 36.466667' );
    x = altazToradec( 49.169122, 269.14634, 52.5, 0, new Date('August 10, 1998 23:10:00 GMT+0000') );
    console.log( x );