Matrix3D HorizontalToEquatorialMatrix( Angle localSiderealTime, Angle geographicLatitude ) { // This is equivalent to // Matrix3D( 2, -lst ) * Matrix3D( 1,0,0, 0,-1,0, 0,0,1 ) // * Matrix3D( 1, lat - pi/2 ) * Matrix3D( 2, pi ). double sinLST = localSiderealTime.Sin( ); double cosLST = localSiderealTime.Cos( ); double sinLat = geographicLatitude.Sin( ); double cosLat = geographicLatitude.Cos( ); return Matrix3D( - cosLST * sinLat, - sinLST, cosLST * cosLat, - sinLST * sinLat, cosLST, sinLST * cosLat, cosLat, 0, sinLat ); }
Point3D Geodetic::Rectangular( ) const { double sinLat = m_latitude.Sin( ); double cosLat = m_latitude.Cos( ); double sinLong = m_longitude.Sin( ); double cosLong = m_longitude.Cos( ); double eccentricity = std::sqrt( 2 * flattening - flattening * flattening ); double eccentSqr = eccentricity * eccentricity; double radCurv = radius / sqrt( 1. - eccentSqr * sinLat * sinLat ); return Point3D( (radCurv + m_height) * cosLat * cosLong, (radCurv + m_height) * cosLat * sinLong, ((1 + eccentSqr) * radCurv + m_height) * sinLat ); }
Horizontal EquatorialToHorizontal( const Equatorial & equatorial, Angle localSiderealTime, Angle geographicLatitude ) { Angle hourAngle = localSiderealTime - equatorial.RightAscension(); double sinHA = hourAngle.Sin( ); double cosHA = hourAngle.Cos( ); double sinDec = equatorial.Declination().Sin( ); double cosDec = equatorial.Declination().Cos( ); double tanDec = (cosDec == 0.) ? infinity : sinDec / cosDec; double sinLat = geographicLatitude.Sin( ); double cosLat = geographicLatitude.Cos( ); Angle az = ArcTan( sinHA, cosHA * sinLat - tanDec * cosLat ); az += Angle( M_PI ); az.NormalizePositive( ); Angle alt = ArcSin( sinDec * sinLat + cosHA * cosDec * cosLat ); return Horizontal( az, alt, equatorial.Distance() ); }
Equatorial HorizontalToEquatorial( const Horizontal & horizontal, Angle localSiderealTime, Angle geographicLatitude ) { Angle az = horizontal.Azimuth() - Angle( M_PI ); double sinAz = az.Sin( ); double cosAz = az.Cos( ); double sinAlt = horizontal.Altitude().Sin( ); double cosAlt = horizontal.Altitude().Cos( ); double tanAlt = (cosAlt == 0.) ? infinity : sinAlt / cosAlt; double sinLat = geographicLatitude.Sin( ); double cosLat = geographicLatitude.Cos( ); // (Meeus has an error here, which I've corrected.) Angle hourAngle = ArcTan( sinAz, cosAz * sinLat + tanAlt * cosLat ); Angle ra = localSiderealTime - hourAngle; ra.NormalizePositive( ); Angle dec = ArcSin( sinAlt * sinLat - cosAz * cosAlt * cosLat ); return Equatorial( ra, dec, horizontal.Distance() ); }
Angle EclipticalLongitude( const Point3D & equatorialRect, Angle obliquity ) { double x = equatorialRect.X(); double y = obliquity.Cos() * equatorialRect.Y() + obliquity.Sin() * equatorialRect.Z(); if ( (x == 0.) && (y == 0.) ) return Angle( 0. ); else return ArcTan( y, x ); }
void Geodetic::Set( const Point3D & rectangular ) { //Explanatory Supplement (4.22-11 to 4.22-24) double X = rectangular.X(); double Y = rectangular.Y(); double Z = rectangular.Z(); double a = radius; double b = a - flattening * a; if ( Z < 0.) b = -b; if ( (X == 0.) && (Y == 0.) ) { m_longitude.Set( 0. ); m_latitude.Set( 0. ); m_height = Z - b; if ( m_height < 0. ) m_height = - m_height; return; } else m_longitude = ArcTan( Y, X ); if ( Z == 0.) { m_latitude.Set( 0. ); m_height.Set( r - radius ); return; } double r = std::sqrt( X * X + Y * Y ); double aSqr = a * a; double bSqr = b * b; double E = (b * Z - (aSqr - bSqr)) / (a * r); double ESqr = E * E; double F = (b * Z + (aSqr + bSqr)) / (a * r); double P = (4./3.) * (E * F + 1.); double Q = 2. * (ESqr - F * F); double D = P * P * P + Q * Q; double sqrtD = std::sqrt( D ); double v = std::pow( (sqrtD - Q), (1./3.) ) - std::pow( (sqrtD + Q), (1./3.) ); const double epsilon = 1.0; if ( (std::fabs( Z ) < epsilon ) || (std::fabs( r ) < epsilon) ) v = - (v * v * v + 2. * Q) / (3. * P); double G = 0.5 * (std::sqrt( ESqr + v ) + E); double t = std::sqrt( G * G + (F - v * G) / (G + G - E) ) - G; m_latitude = ArcTan( (a * (1. - t * t)), (2. * b * t) ); m_height = (r - a * t) * m_latitude.Cos( ) + (Z - b) * m_latitude.Sin( ); }
Ecliptical EquatorialToEcliptical( const Equatorial & equatorial, Angle obliquity ) { double sinRA = equatorial.RightAscension().Sin( ); double cosRA = equatorial.RightAscension().Cos( ); double sinDec = equatorial.Declination().Sin( ); double cosDec = equatorial.Declination().Cos( ); double tanDec = (cosDec == 0.) ? infinity : sinDec / cosDec; double sinObl = obliquity.Sin( ); double cosObl = obliquity.Cos( ); Angle lng = ArcTan( sinRA * cosObl + tanDec * sinObl, cosRA ); lng.NormalizePositive( ); Angle lat = ArcSin( sinDec * cosObl - sinRA * cosDec * sinObl ); return Ecliptical( lng, lat, equatorial.Distance() ); }
Equatorial EclipticalToEquatorial( const Ecliptical & ecliptical, Angle obliquity ) { double sinLong = ecliptical.Longitude().Sin( ); double cosLong = ecliptical.Longitude().Cos( ); double sinLat = ecliptical.Latitude().Sin( ); double cosLat = ecliptical.Latitude().Cos( ); double tanLat = (cosLat == 0.) ? infinity : sinLat / cosLat; double sinObl = obliquity.Sin( ); double cosObl = obliquity.Cos( ); Angle ra = ArcTan( sinLong * cosObl - tanLat * sinObl, cosLong ); ra.NormalizePositive( ); Angle dec = ArcSin( sinLat * cosObl + sinLong * cosLat * sinObl ); return Equatorial( ra, dec, ecliptical.Distance() ); }
void Matrix3<T>::Set( int axis, const Angle & angle ) { if ( (axis < 0) || (axis >= 3) ) throw std::out_of_range( "Matrix3: out_of_range error" ); static const int indices[3][3] = { { 0, 1, 2 }, { 1, 2, 0 }, { 2, 0, 1 } }; const int i0 = indices[ axis ][ 0 ]; const int i1 = indices[ axis ][ 1 ]; const int i2 = indices[ axis ][ 2 ]; const T cos = static_cast< T >( angle.Cos( ) ); const T sin = static_cast< T >( angle.Sin( ) ); m_elements[ i0 ][ i0 ] = 1.; m_elements[ i0 ][ i1 ] = m_elements[ i0 ][ i2 ] = m_elements[ i1 ][ i0 ] = m_elements[ i2 ][ i0 ] = 0.; m_elements[ i1 ][ i1 ] = m_elements[ i2 ][ i2 ] = cos; m_elements[ i2 ][ i1 ] = - sin; m_elements[ i1 ][ i2 ] = sin; }
Equatorial GalacticToEquatorial( const Galactic & galactic ) { Angle galNorthRAAdj( 192.25 - 180., Angle::Degree ); Angle galNorthDec( 27.4, Angle::Degree ); Angle longOffset( 33. + 90., Angle::Degree ); Angle adjLong = galactic.Longitude() - longOffset; double sinAdjLong = adjLong.Sin( ); double cosAdjLong = adjLong.Cos( ); double sinLat = galactic.Latitude().Sin( ); double cosLat = galactic.Latitude().Cos( ); double tanLat = (cosLat == 0.) ? infinity : sinLat / cosLat; double sinNDec = galNorthDec.Sin( ); double cosNDec = galNorthDec.Cos( ); Angle y = ArcTan( sinAdjLong, cosAdjLong * sinNDec - tanLat * cosNDec ); Angle ra = y + galNorthRAAdj; ra.NormalizePositive( ); Angle dec = ArcSin( sinLat * sinNDec + cosAdjLong * cosLat * cosNDec ); return Equatorial( ra, dec, galactic.Distance() ); }
Galactic EquatorialToGalactic( const Equatorial & equatorial ) { Angle galNorthRA( 192.25, Angle::Degree ); Angle galNorthDec( 27.4, Angle::Degree ); Angle longOffset( 33. + 270., Angle::Degree ); Angle adjRA = galNorthRA - equatorial.RightAscension(); double sinAdjRA = adjRA.Sin( ); double cosAdjRA = adjRA.Cos( ); double sinDec = equatorial.Declination().Sin( ); double cosDec = equatorial.Declination().Cos( ); double tanDec = (cosDec == 0.) ? infinity : sinDec / cosDec; double sinNDec = galNorthDec.Sin( ); double cosNDec = galNorthDec.Cos( ); Angle x = ArcTan( sinAdjRA, cosAdjRA * sinNDec - tanDec * cosNDec ); Angle lng = longOffset - x; lng.NormalizePositive( ); Angle lat = ArcSin( sinDec * sinNDec + cosAdjRA * cosDec * cosNDec ); return Galactic( lng, lat, equatorial.Distance() ); }
void Matrix3<T>::Set( const AxisAngle<T> & axisAngle ) { Angle angle = axisAngle.GetAngle( ); const Vector3<T> & axis = axisAngle.Axis( ); const T cc = static_cast<T>( 1. - angle.Cos( ) ); const T s = static_cast<T>( angle.Sin( ) ); const T a00 = axis[0] * axis[0]; const T a01 = axis[0] * axis[1]; const T a02 = axis[0] * axis[2]; const T a11 = axis[1] * axis[1]; const T a12 = axis[1] * axis[2]; const T a22 = axis[2] * axis[2]; m_elements[0][0] = static_cast<T>( 1. - cc * (a11 + a22) ); m_elements[1][0] = static_cast<T>( -s * axis[2] + cc * a01 ); m_elements[2][0] = static_cast<T>( s * axis[1] + cc * a02 ); m_elements[0][1] = static_cast<T>( s * axis[2] + cc * a01 ); m_elements[1][1] = static_cast<T>( 1. - cc * (a00 + a22) ); m_elements[2][1] = static_cast<T>( -s * axis[0] + cc * a12 ); m_elements[0][2] = static_cast<T>( -s * axis[1] + cc * a02 ); m_elements[1][2] = static_cast<T>( s * axis[0] + cc * a12 ); m_elements[2][2] = static_cast<T>( 1. - cc * (a00 + a11) ); }