예제 #1
0
        /// <summary>
        /// 时差计算(高精度)
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static double shiCha(double t)
        {
            double t2 = t * t, t3 = t2 * t, t4 = t3 * t, t5 = t4 * t;
            double L = (1753469512 + 628331965331.8 * t + 5296.74 * t2 + 0.432 * t3 - 0.1124 * t4 - 0.00009 * t5 + 630 * Math.Cos(6 + 0.3 * t)) / 1000000000 + Math.PI - 20.5 / LunarHelper.rad;

            double E, dE, dL;

            double[] z = new double[2];                                     // C#: 待定(?)
            dL = -17.2 * Math.Sin(2.1824 - 33.75705 * t) / LunarHelper.rad; //黄经章
            dE = 9.2 * Math.Cos(2.1824 - 33.75705 * t) / LunarHelper.rad;   //交角章
            E  = ZB.hcjj(t) + dE;                                           //真黄赤交角

            //地球坐标
            z[0] = XL.E_Lon(t, 50) + Math.PI + ZB.gxc_sunLon(t) + dL;
            z[1] = -(2796 * Math.Cos(3.1987 + 8433.46616 * t) + 1016 * Math.Cos(5.4225 + 550.75532 * t) + 804 * Math.Cos(3.88 + 522.3694 * t)) / 1000000000;

            ZB.llrConv(z, E); //z太阳地心赤道坐标
            z[0] -= dL * Math.Cos(E);

            L = LunarHelper.rad2mrad(L - z[0]);
            if (L > Math.PI)
            {
                L -= LunarHelper.pi2;
            }
            return(L / LunarHelper.pi2); //单位是周(天)
        }
예제 #2
0
 /// <summary>
 /// 章动同时影响恒星时和天体坐标,所以不计算章动。返回时角及赤经纬
 /// </summary>
 /// <param name="jd"></param>
 /// <param name="H0"></param>
 /// <param name="z"></param>
 public static void Mcoord(double jd, double H0, LunarInfoListT <double> z)
 {
     XL.M_coord((jd + SZJ.dt) / 36525, z, 30, 20, 8); //低精度月亮赤经纬
     ZB.llrConv(z, SZJ.E);                            //转为赤道坐标
     z.H = LunarHelper.rad2mrad(ZB.gst(jd, SZJ.dt) - SZJ.L - z[0]);
     if (z.H > Math.PI)
     {
         z.H -= LunarHelper.pi2;                //得到此刻天体时角
     }
     if (H0 != 0)
     {
         z.H0 = SZJ.getH(0.7275 * LunarHelper.cs_rEar / z[2] - 34 * 60 / LunarHelper.rad, z[1]);          //升起对应的时角
     }
 }
예제 #3
0
 /// <summary>
 /// 章动同时影响恒星时和天体坐标,所以不计算章动。返回时角及赤经纬
 /// </summary>
 /// <param name="jd"></param>
 /// <param name="H0"></param>
 /// <param name="H1"></param>
 /// <param name="z"></param>
 public static void Scoord(double jd, double H0, double H1, LunarInfoListT <double> z)
 {
     z[0] = XL.E_Lon((jd + SZJ.dt) / 36525, 5) + Math.PI - 20.5 / LunarHelper.rad; //太阳坐标(修正了光行差)
     z[1] = 0d; z[2] = 1d;                                                         // C#: 添加 d, 强制为 double 类型, 否则在把该元素显式转换为 double 时会出错
     ZB.llrConv(z, SZJ.E);                                                         // 转为赤道坐标
     z.H = LunarHelper.rad2rrad(ZB.gst(jd, SZJ.dt) - SZJ.L - z[0]);                //得到此刻天体时角
     if (H0 != 0)
     {
         z.H0 = SZJ.getH(-50 * 60 / LunarHelper.rad, z[1]);           //地平以下50分
     }
     if (H1 != 0)
     {
         z.H1 = SZJ.getH(-Math.PI / 30, z[1]);           // 地平以下6度
     }
 }
예제 #4
0
        /// <summary>
        /// 时差计算(低精度),误差约在1秒以内
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static double shiCha2(double t)
        {
            double L = (1753469512 + 628331965331.8 * t + 5296.74 * t * t) / 1000000000 + Math.PI;

            double[] z = new double[2];    // C#: 待定(?)
            double   E = (84381.4088 - 46.836051 * t) / LunarHelper.rad;

            z[0] = XL.E_Lon(t, 5) + Math.PI; z[1] = 0; // 地球坐标
            ZB.llrConv(z, E);                          // z太阳地心赤道坐标
            L = LunarHelper.rad2mrad(L - z[0]);
            if (L > Math.PI)
            {
                L -= LunarHelper.pi2;
            }
            return(L / LunarHelper.pi2);     // 单位是周(天)
        }
예제 #5
0
        /// <summary>
        /// 月亮到中升降时刻计算,传入jd含义与St()函数相同
        /// </summary>
        /// <param name="jd"></param>
        /// <returns></returns>
        public static LunarInfoListT <double> Mt(double jd)
        {
            SZJ.dt = JD.deltatT2(jd);
            SZJ.E  = ZB.hcjj(jd / 36525);
            jd    -= LunarHelper.mod2(0.1726222 + 0.966136808032357 * jd - 0.0366 * SZJ.dt - SZJ.L / LunarHelper.pi2, 1); //查找最靠近当日中午的月上中天,mod2的第1参数为本地时角近似值

            LunarInfoListT <double> r = new LunarInfoListT <double>(3, 0d);
            double sv = LunarHelper.pi2 * 0.966;

            r.z__ = r.s__ = r.j__ = r.c__ = r.h__ = jd;
            SZJ.Mcoord(jd, 1, r); //月亮坐标
            r.s__ += (-r.H0 - r.H) / sv;
            r.j__ += (r.H0 - r.H) / sv;
            r.z__ += (0 - r.H) / sv;
            SZJ.Mcoord(r.s__, 1, r); r.s__ += (-r.H0 - r.H) / sv;
            SZJ.Mcoord(r.j__, 1, r); r.j__ += (+r.H0 - r.H) / sv;
            SZJ.Mcoord(r.z__, 0, r); r.z__ += (0 - r.H) / sv;
            return(r);
        }
예제 #6
0
        /// <summary>
        /// 太阳到中升降时刻计算,传入jd是当地中午12点时间对应的2000年首起算的格林尼治时间UT
        /// </summary>
        /// <param name="jd"></param>
        /// <returns></returns>
        public static LunarInfoListT <double> St(double jd)
        {
            SZJ.dt = JD.deltatT2(jd);
            SZJ.E  = ZB.hcjj(jd / 36525);
            jd    -= LunarHelper.mod2(jd - SZJ.L / LunarHelper.pi2, 1); //查找最靠近当日中午的日上中天,mod2的第1参数为本地时角近似值

            LunarInfoListT <double> r = new LunarInfoListT <double>(3, 0d);
            double sv = LunarHelper.pi2;

            r.z__ = r.s__ = r.j__ = r.c__ = r.h__ = jd;
            SZJ.Scoord(jd, 1, 1, r);       //太阳坐标
            r.s__ += (-r.H0 - r.H) / sv;   //升起
            r.j__ += (r.H0 - r.H) / sv;    //降落
            r.c__ += (-r.H1 - r.H) / sv;   //民用晨
            r.h__ += (r.H1 - r.H) / sv;    //民用昏
            r.z__ += (0 - r.H) / sv;       //中天
            SZJ.Scoord(r.s__, 1, 0, r); r.s__ += (-r.H0 - r.H) / sv;
            SZJ.Scoord(r.j__, 1, 0, r); r.j__ += (+r.H0 - r.H) / sv;
            SZJ.Scoord(r.c__, 0, 1, r); r.c__ += (-r.H1 - r.H) / sv;
            SZJ.Scoord(r.h__, 0, 1, r); r.h__ += (+r.H1 - r.H) / sv;
            SZJ.Scoord(r.z__, 0, 0, r); r.z__ += (0 - r.H) / sv;
            return(r);
        }
예제 #7
0
        /// <summary>
        /// 视差修正
        /// </summary>
        /// <param name="z">赤道坐标</param>
        /// <param name="H">时角</param>
        /// <param name="fa">地理纬度</param>
        /// <param name="high">海拔(千米)</param>
        public static void parallax(double[] z, double H, double fa, double high)
        {
            double dw = 1d;

            if (z[2] < 500)
            {
                dw = LunarHelper.cs_AU;
            }
            z[2] *= dw;
            double r0, x0, y0, z0, f = 0.99664719;
            double u = Math.Atan(f * Math.Tan(fa));
            double g = z[0] + H;

            r0 = LunarHelper.cs_rEar * Math.Cos(u) + high * Math.Cos(fa);     //站点与地地心向径的赤道投影长度
            z0 = LunarHelper.cs_rEar * Math.Sin(u) * f + high * Math.Sin(fa); //站点与地地心向径的轴向投影长度
            x0 = r0 * Math.Cos(g);
            y0 = r0 * Math.Sin(g);

            ZB.llr2xyz(z[0], z[1], z[2], z);
            z[0] -= x0; z[1] -= y0; z[2] -= z0;
            ZB.xyz2llr(z[0], z[1], z[2], z);
            z[2] /= dw;
        }
예제 #8
0
 /// <summary>
 /// 太阳视黄经
 /// </summary>
 /// <param name="t"></param>
 /// <param name="n"></param>
 /// <returns></returns>
 public static double S_aLon(double t, double n)
 {
     return(XL.E_Lon(t, n) + ZB.nutationLon(t) + ZB.gxc_sunLon(t) + Math.PI); //注意,这里的章动计算很耗时
 }
예제 #9
0
 /// <summary>
 /// 月日视黄经的差值
 /// </summary>
 /// <param name="t"></param>
 /// <param name="Mn"></param>
 /// <param name="Sn"></param>
 /// <returns></returns>
 public static double MS_aLon(double t, double Mn, double Sn)
 {
     return(XL.M_Lon(t, Mn) + ZB.gxc_moonLon(t) - (XL.E_Lon(t, Sn) + ZB.gxc_sunLon(t) + Math.PI));
 }
예제 #10
0
        }                                   // = 0;

        #endregion

        #endregion 公共属性



        #region 公共方法
        /// <summary>
        /// 计算 sun_moon 类的成员。参数:T是力学时,站点经度L,纬度fa,海拔high(千米)
        /// </summary>
        /// <param name="T">力学时</param>
        /// <param name="L">站点经度</param>
        /// <param name="fa">站点纬度</param>
        /// <param name="high">海拔</param>
        public void calc(double T, double L, double fa, double high)
        {
            //基本参数计算
            this.T   = T;
            this.L   = L; this.fa = fa;
            this.dt  = JD.deltatT2(T);                                        //TD-UT
            this.jd  = T - this.dt;                                           //UT
            T       /= 36525; ZB.nutation(T);
            this.dL  = ZB.dL;                                                 //黄经章
            this.dE  = ZB.dE;                                                 //交角章动
            this.E   = ZB.hcjj(T) + this.dE;                                  //真黄赤交角
            this.gst = ZB.gst(this.jd, this.dt) + this.dL * Math.Cos(this.E); //真恒星时(不考虑非多项式部分)
            double[] z = new double[4];

            //=======月亮========
            //月亮黄道坐标
            XL.M_coord(T, z, -1, -1, -1);                                                                   //月球坐标
            z[0]     = LunarHelper.rad2mrad(z[0] + ZB.gxc_moonLon(T) + this.dL); z[1] += ZB.gxc_moonLat(T); //补上月球光行差及章动
            this.mHJ = z[0]; this.mHW = z[1]; this.mR = z[2];                                               //月球视黄经,视黄纬,地月质心距

            //月球赤道坐标
            ZB.llrConv(z, this.E);            //转为赤道坐标
            this.mCJ = z[0]; this.mCW = z[1]; //月球视赤经,月球赤纬

            //月亮时角计算
            this.mShiJ = LunarHelper.rad2mrad(this.gst - L - z[0]); //得到此刻天体时角
            if (this.mShiJ > Math.PI)
            {
                this.mShiJ -= LunarHelper.pi2;
            }

            //修正了视差的赤道坐标
            ZB.parallax(z, this.mShiJ, fa, high); //视差修正
            this.mCJ2 = z[0]; this.mCW2 = z[1]; this.mR2 = z[2];

            //月亮时角坐标
            z[0] += Math.PI / 2d - this.gst + L;  //转到相对于地平赤道分点的赤道坐标(时角坐标)

            //月亮地平坐标
            ZB.llrConv(z, Math.PI / 2 - fa);  //转到地平坐标(只改经纬度)
            z[0]     = LunarHelper.rad2mrad(Math.PI / 2 - z[0]);
            this.mDJ = z[0]; this.mDW = z[1]; //方位角,高度角
            if (z[1] > 0)
            {
                z[1] += ZB.AR2(z[1]);         //大气折射修正
            }
            this.mPJ = z[0]; this.mPW = z[1]; //方位角,高度角

            //=======太阳========
            //太阳黄道坐标
            XL.E_coord(T, z, -1, -1, -1);                                                 //地球坐标
            z[0]     = LunarHelper.rad2mrad(z[0] + Math.PI + ZB.gxc_sunLon(T) + this.dL); //补上太阳光行差及章动
            z[1]     = -z[1] + ZB.gxc_sunLat(T);                                          //z数组为太阳地心黄道视坐标
            this.sHJ = z[0]; this.sHW = z[1]; this.sR = z[2];                             //太阳视黄经,视黄纬,日地质心距

            //太阳赤道坐标
            ZB.llrConv(z, this.E);            //转为赤道坐标
            this.sCJ = z[0]; this.sCW = z[1]; //太阳视赤经,视赤纬

            //太阳时角计算
            this.sShiJ = LunarHelper.rad2mrad(this.gst - L - z[0]); //得到此刻天体时角
            if (this.sShiJ > Math.PI)
            {
                this.sShiJ -= LunarHelper.pi2;
            }

            //修正了视差的赤道坐标
            ZB.parallax(z, this.sShiJ, fa, high); //视差修正
            this.sCJ2 = z[0]; this.sCW2 = z[1]; this.sR2 = z[2];

            //太阳时角坐标
            z[0] += Math.PI / 2 - this.gst + L;  //转到相对于地平赤道分点的赤道坐标

            //太阳地平坐标
            ZB.llrConv(z, Math.PI / 2 - fa);
            z[0] = LunarHelper.rad2mrad(Math.PI / 2 - z[0]);
            //z[1] -= 8.794/rad/z[2]*Math.cos(z[1]); //直接在地平坐标中视差修正(这里把地球看为球形,精度比ZB.parallax()稍差一些)
            this.sDJ = z[0]; this.sDW = z[1]; //方位角,高度角

            if (z[1] > 0)
            {
                z[1] += ZB.AR2(z[1]);         //大气折射修正
            }
            this.sPJ = z[0]; this.sPW = z[1]; //方位角,高度角

            //=======其它========
            //时差计算
            double t = T / 10; double t2 = t * t, t3 = t2 * t, t4 = t3 * t, t5 = t4 * t;
            double Lon = (1753469512 + 6283319653318 * t + 529674 * t2 + 432 * t3 - 1124 * t4 - 9 * t5 + 630 * Math.Cos(6 + 3 * t)) / 1000000000 + Math.PI - 20.5 / LunarHelper.rad; //修正了光行差的太阳平黄经

            Lon = LunarHelper.rad2mrad(Lon - (this.sCJ - this.dL * Math.Cos(this.E)));                                                                                               //(修正了光行差的平黄经)-(不含dL*cos(E)的视赤经)
            if (Lon > Math.PI)
            {
                Lon -= LunarHelper.pi2;        //得到时差,单位是弧度
            }
            this.sc = Lon / LunarHelper.pi2;   //时差(单位:日)

            //真太阳与平太阳
            this.pty = this.jd - L / LunarHelper.pi2;           //平太阳时
            this.zty = this.jd - L / LunarHelper.pi2 + this.sc; //真太阳时

            //视半径
            //this.mRad = XL.moonRad(this.mR,this.mDW);  //月亮视半径(角秒)
            this.mRad     = 358473400d / this.mR2;                                                                     //月亮视半径(角秒)
            this.sRad     = 959.63 / this.sR2;                                                                         //太阳视半径(角秒)
            this.e_mRad   = 358473400d / this.mR;                                                                      //月亮地心视半径(角秒)
            this.eShadow  = (LunarHelper.cs_rEarA / this.mR * LunarHelper.rad - (959.63 - 8.794) / this.sR) * 51 / 50; //地本影在月球向径处的半径(角秒),式中51/50是大气厚度补偿
            this.eShadow2 = (LunarHelper.cs_rEarA / this.mR * LunarHelper.rad + (959.63 + 8.794) / this.sR) * 51 / 50; //地半影在月球向径处的半径(角秒),式中51/50是大气厚度补偿
            this.mIll     = XL.moonIll(T);                                                                             //月亮被照面比例

            //中心食计算
            if (Math.Abs(LunarHelper.rad2rrad(this.mCJ - this.sCJ)) < 50 / 180 * Math.PI)
            {
                ZB.line_earth(this.mCJ, this.mCW, this.mR, this.sCJ, this.sCW, this.sR * LunarHelper.cs_AU);
                this.zx_J = LunarHelper.rad2rrad(this.gst - ZB.le_J);
                this.zx_W = ZB.le_W; //无解返回值是100
            }
            else
            {
                this.zx_J = this.zx_W = 100;
            }
        }