double 
MoonPhases::FindNext( double julianDay, Angle phaseAngle )
{
    const double synodicMonth = 29.5305888531;
    Angle lunarPhase = LunarPhase( julianDay );
    Angle phaseDiff = phaseAngle - lunarPhase;
    phaseDiff.NormalizePositive( );
    double offset = phaseDiff.Cycles() * synodicMonth;
    double estimate = julianDay + offset;
    double lowEst = estimate - 0.5;
    double highEst = estimate + 0.5;
    MoonPhaseFunc phaseFunc( phaseAngle );
#ifdef DEBUG
    bool brcktRslt =
#endif
            RootFinder::BracketRoot( phaseFunc, &lowEst, &highEst );
    Assert( brcktRslt );
    double phaseJD;
#ifdef DEBUG
    bool rootRslt =
#endif
            RootFinder::Brent( phaseFunc, &phaseJD, lowEst, highEst, 1.e-4 );
    Assert( rootRslt );
    double ut_tdb = - TDB_UT( phaseJD ).Days();
    return  (phaseJD + ut_tdb);
}
inline 
void 
Spherical::NormalizeSemiPositive( )
{
    m_longitude.NormalizePositive( );
    m_latitude.Normalize( );
}
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() );
}
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() );
}
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() );
}