public static RiseSetDetails GetRiseTrinsitSet(double jd, double lat, double lng, double ra1, double dec1, double ra2, double dec2, double ra3, double dec3, int type)
        {
            double alt = -0.5667;

            switch (type)
            {
            case 0:                     // Planet or star
                alt = -0.5667;
                break;

            case 1:                     // sun
                alt = -0.8333;
                break;

            case 2:
                alt = 0.125;
                break;
            }
            CAARiseTransitSetDetails RiseTransitSetTime = CAARiseTransitSet.Rise(jd, ra1, dec1, ra2, dec2, ra3, dec3, lng, lat, alt);

            bool neverRises = false;

            if (!RiseTransitSetTime.bValid)
            {
                neverRises = Util.Sign(lat) != Util.Sign(dec2);
            }

            return(new RiseSetDetails(RiseTransitSetTime.bValid, RiseTransitSetTime.Rise, RiseTransitSetTime.Transit, RiseTransitSetTime.Set, neverRises));
        }
    //Static methods
    ///////////////////////////// Implementation //////////////////////////////////
    public static CAARiseTransitSetDetails Rise(double JD, double Alpha1, double Delta1, double Alpha2, double Delta2, double Alpha3, double Delta3, double Longitude, double Latitude, double h0)
    {
        //What will be the return value
        CAARiseTransitSetDetails details = new CAARiseTransitSetDetails();
        details.bValid = false;

        //Calculate the sidereal time
        double theta0 = CAASidereal.ApparentGreenwichSiderealTime(JD);
        theta0 *= 15; //Express it as degrees

        //Calculate deltat
        double deltaT = CAADynamicalTime.DeltaT(JD);

        //Convert values to radians
        double Delta2Rad = CAACoordinateTransformation.DegreesToRadians(Delta2);
        double LatitudeRad = CAACoordinateTransformation.DegreesToRadians(Latitude);

        //Convert the standard latitude to radians
        double h0Rad = CAACoordinateTransformation.DegreesToRadians(h0);

        double cosH0 = (Math.Sin(h0Rad) - Math.Sin(LatitudeRad)*Math.Sin(Delta2Rad)) / (Math.Cos(LatitudeRad) * Math.Cos(Delta2Rad));

        //Check that the object actually rises
        if ((cosH0 > 1) || (cosH0 < -1))
          return details;

        double H0 = Math.Acos(cosH0);
        H0 = CAACoordinateTransformation.RadiansToDegrees(H0);

        double M0 = (Alpha2 *15 + Longitude - theta0) / 360;
        double M1 = M0 - H0/360;
        double M2 = M0 + H0/360;

        if (M0 > 1)
          M0 -= 1;
        else if (M0 < 0)
          M0 += 1;

        if (M1 > 1)
          M1 -= 1;
        else if (M1 < 0)
          M1 += 1;

        if (M2 > 1)
          M2 -= 1;
        else if (M2 < 0)
          M2 += 1;

        for (int i =0; i<2; i++)
        {
          //Calculate the details of rising

          double theta1 = theta0 + 360.985647 *M1;
          theta1 = CAACoordinateTransformation.MapTo0To360Range(theta1);

          double n = M1 + deltaT/86400;

          double Alpha = CAAInterpolate.Interpolate(n, Alpha1, Alpha2, Alpha3);
          double Delta = CAAInterpolate.Interpolate(n, Delta1, Delta2, Delta3);

          double H = theta1 - Longitude - Alpha *15;
          CAA2DCoordinate Horizontal = CAACoordinateTransformation.Equatorial2Horizontal(H/15, Delta, Latitude);

          double DeltaM = (Horizontal.Y - h0) / (360 *Math.Cos(CAACoordinateTransformation.DegreesToRadians(Delta))*Math.Cos(LatitudeRad)*Math.Sin(CAACoordinateTransformation.DegreesToRadians(H)));
          M1 += DeltaM;

          //Calculate the details of transit

          theta1 = theta0 + 360.985647 *M0;
          theta1 = CAACoordinateTransformation.MapTo0To360Range(theta1);

          n = M0 + deltaT/86400;

          Alpha = CAAInterpolate.Interpolate(n, Alpha1, Alpha2, Alpha3);

          H = theta1 - Longitude - Alpha *15;

          if (H < -180)
          {
          H+=360;
          }

          DeltaM = -H / 360;
          M0 += DeltaM;

          //Calculate the details of setting

          theta1 = theta0 + 360.985647 *M2;
          theta1 = CAACoordinateTransformation.MapTo0To360Range(theta1);

          n = M2 + deltaT/86400;

          Alpha = CAAInterpolate.Interpolate(n, Alpha1, Alpha2, Alpha3);
          Delta = CAAInterpolate.Interpolate(n, Delta1, Delta2, Delta3);

          H = theta1 - Longitude - Alpha *15;
          Horizontal = CAACoordinateTransformation.Equatorial2Horizontal(H/15, Delta, Latitude);

          DeltaM = (Horizontal.Y - h0) / (360 *Math.Cos(CAACoordinateTransformation.DegreesToRadians(Delta))*Math.Cos(LatitudeRad)*Math.Sin(CAACoordinateTransformation.DegreesToRadians(H)));
          M2 += DeltaM;
        }

        //Finally before we exit, convert to hours
        details.bValid = true;
        details.Rise = M1 * 24;
        details.Set = M2 * 24;
        details.Transit = M0 * 24;

        return details;
    }
//Static methods

    ///////////////////////////// Implementation //////////////////////////////////

    public static CAARiseTransitSetDetails Rise(double JD, double Alpha1, double Delta1, double Alpha2, double Delta2, double Alpha3, double Delta3, double Longitude, double Latitude, double h0)
    {
        //What will be the return value
        CAARiseTransitSetDetails details = new CAARiseTransitSetDetails();

        details.bValid = false;

        //Calculate the sidereal time
        double theta0 = CAASidereal.ApparentGreenwichSiderealTime(JD);

        theta0 *= 15; //Express it as degrees

        //Calculate deltat
        double deltaT = DYT.DeltaT(JD);

        //Convert values to radians
        double Delta2Rad   = CT.D2R(Delta2);
        double LatitudeRad = CT.D2R(Latitude);

        //Convert the standard latitude to radians
        double h0Rad = CT.D2R(h0);

        double cosH0 = (Math.Sin(h0Rad) - Math.Sin(LatitudeRad) * Math.Sin(Delta2Rad)) / (Math.Cos(LatitudeRad) * Math.Cos(Delta2Rad));

        //Check that the object actually rises
        if ((cosH0 > 1) || (cosH0 < -1))
        {
            return(details);
        }

        double H0 = Math.Acos(cosH0);

        H0 = CT.R2D(H0);

        double M0 = (Alpha2 * 15 + Longitude - theta0) / 360;
        double M1 = M0 - H0 / 360;
        double M2 = M0 + H0 / 360;

        if (M0 > 1)
        {
            M0 -= 1;
        }
        else if (M0 < 0)
        {
            M0 += 1;
        }

        if (M1 > 1)
        {
            M1 -= 1;
        }
        else if (M1 < 0)
        {
            M1 += 1;
        }

        if (M2 > 1)
        {
            M2 -= 1;
        }
        else if (M2 < 0)
        {
            M2 += 1;
        }

        for (int i = 0; i < 2; i++)
        {
            //Calculate the details of rising

            double theta1 = theta0 + 360.985647 * M1;
            theta1 = CT.M360(theta1);

            double n = M1 + deltaT / 86400;

            double Alpha = INTP.Interpolate(n, Alpha1, Alpha2, Alpha3);
            double Delta = INTP.Interpolate(n, Delta1, Delta2, Delta3);

            double H          = theta1 - Longitude - Alpha * 15;
            COR    Horizontal = CT.Eq2H(H / 15, Delta, Latitude);

            double DeltaM = (Horizontal.Y - h0) / (360 * Math.Cos(CT.D2R(Delta)) * Math.Cos(LatitudeRad) * Math.Sin(CT.D2R(H)));
            M1 += DeltaM;


            //Calculate the details of transit

            theta1 = theta0 + 360.985647 * M0;
            theta1 = CT.M360(theta1);

            n = M0 + deltaT / 86400;

            Alpha = INTP.Interpolate(n, Alpha1, Alpha2, Alpha3);

            H = theta1 - Longitude - Alpha * 15;

            if (H < -180)
            {
                H += 360;
            }

            DeltaM = -H / 360;
            M0    += DeltaM;


            //Calculate the details of setting

            theta1 = theta0 + 360.985647 * M2;
            theta1 = CT.M360(theta1);

            n = M2 + deltaT / 86400;

            Alpha = INTP.Interpolate(n, Alpha1, Alpha2, Alpha3);
            Delta = INTP.Interpolate(n, Delta1, Delta2, Delta3);

            H          = theta1 - Longitude - Alpha * 15;
            Horizontal = CT.Eq2H(H / 15, Delta, Latitude);

            DeltaM = (Horizontal.Y - h0) / (360 * Math.Cos(CT.D2R(Delta)) * Math.Cos(LatitudeRad) * Math.Sin(CT.D2R(H)));
            M2    += DeltaM;
        }

        //Finally before we exit, convert to hours
        details.bValid  = true;
        details.Rise    = M1 * 24;
        details.Set     = M2 * 24;
        details.Transit = M0 * 24;

        return(details);
    }