⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eph.js

📁 寿星万年历 基于天文算法的万年历 javascript 年代范围大 精度高
💻 JS
📖 第 1 页 / 共 5 页
字号:
//=========日月升降物件=============

var SZJ={//日月的升中天降,不考虑气温和气压的影响
 L  : 0,  //站点地理经度,向东测量为负
 fa : 0,  //站点地理纬度
 dt : 0,  //TD-UT
 E  : 0.409092614, //黄赤交角
 getH:function(h,w){ //h地平纬度,w赤纬,返回时角
  var c = ( Math.sin(h) - Math.sin(this.fa)*Math.sin(w) ) / Math.cos(this.fa)/Math.cos(w);
  if(Math.abs(c)>1) return Math.PI;
  return Math.acos(c);
 },

 Mcoord:function(jd,H0,z){ //章动同时影响恒星时和天体坐标,所以不计算章动。返回时角及赤经纬
   XL.M_coord( (jd+this.dt)/36525, z, 30,20,8 ); //低精度月亮赤经纬
   ZB.llrConv( z, this.E ); //转为赤道坐标
   z.H = rad2mrad(ZB.gst(jd,this.dt) - this.L - z[0]);   if( z.H>Math.PI ) z.H -= pi2; //得到此刻天体时角
   if(H0) z.H0 = this.getH( 0.7275*cs_rEar/z[2]-34*60/rad, z[1] ); //升起对应的时角
 },
 Mt : function(jd){ //月亮到中升降时刻计算,传入jd含义与St()函数相同
  this.dt = JD.deltatT2(jd);
  this.E  = ZB.hcjj(jd/36525);
  jd -= mod2(0.1726222 + 0.966136808032357*jd - 0.0366*this.dt - this.L/pi2, 1); //查找最靠近当日中午的月上中天,mod2的第1参数为本地时角近似值

  var r = new Array(), sv = pi2*0.966;
  r.z = r.s = r.j = r.c = r.h = jd;
  this.Mcoord(jd,1,r); //月亮坐标
  r.s += (-r.H0 - r.H )/sv;
  r.j += ( r.H0 - r.H )/sv;
  r.z += (    0 - r.H )/sv;
  this.Mcoord(r.s,1,r);  r.s += ( -r.H0 - r.H )/sv;
  this.Mcoord(r.j,1,r);  r.j += ( +r.H0 - r.H )/sv;
  this.Mcoord(r.z,0,r);  r.z += (     0 - r.H )/sv;
  return r;
 },

 Scoord:function(jd,H0,H1,z){ //章动同时影响恒星时和天体坐标,所以不计算章动。返回时角及赤经纬
   z[0] = XL.E_Lon( (jd+this.dt)/36525, 5 ) + Math.PI - 20.5/rad;  //太阳坐标(修正了光行差)
   z[1] = 0; z[2]=1;
   ZB.llrConv( z, this.E ); //转为赤道坐标
   z.H = rad2rrad(ZB.gst(jd,this.dt) - this.L - z[0]); //得到此刻天体时角
   if(H0) z.H0 = this.getH(-50*60/rad,z[1]);  //地平以下50分
   if(H1) z.H1 = this.getH(-Math.PI/30,z[1]); //地平以下6度
 },
 St : function(jd){ //太阳到中升降时刻计算,传入jd是当地中午12点时间对应的2000年首起算的格林尼治时间UT
  this.dt = JD.deltatT2(jd);
  this.E  = ZB.hcjj(jd/36525);
  jd -= mod2(jd - this.L/pi2, 1); //查找最靠近当日中午的日上中天,mod2的第1参数为本地时角近似值

  var r = new Array(), sv = pi2;
  r.z = r.s = r.j = r.c = r.h = jd;
  this.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; //中天
  this.Scoord(r.s,1,0,r);  r.s += ( -r.H0 - r.H )/sv;
  this.Scoord(r.j,1,0,r);  r.j += ( +r.H0 - r.H )/sv;
  this.Scoord(r.c,0,1,r);  r.c += ( -r.H1 - r.H )/sv;
  this.Scoord(r.h,0,1,r);  r.h += ( +r.H1 - r.H )/sv;
  this.Scoord(r.z,0,0,r);  r.z += (     0 - r.H )/sv;
  return r;
 },

 rts:new Array(),//多天的升中降
 calcRTS:function(jd,n,Jdl,Wdl,sq){ //多天升中降计算,jd是当地起始略日(中午时刻),sq是时区
  var i,c,r;
  if(!this.rts.length) { for(var i=0;i<31;i++) this.rts[i] = new Array(); }
  this.L = Jdl, this.fa = Wdl, sq/=24; //设置站点参数
  for(i=0;i<n;i++){ r=this.rts[i];  r.Ms=r.Mz=r.Mj=""; }
  for(i=-1;i<=n;i++){
   if(i>=0&&i<n){ //太阳
    r = SZJ.St(jd+i+sq);
    this.rts[i].s = JD.timeStr(r.s-sq); //升
    this.rts[i].z = JD.timeStr(r.z-sq); //中
    this.rts[i].j = JD.timeStr(r.j-sq); //降
    this.rts[i].c = JD.timeStr(r.c-sq); //晨
    this.rts[i].h = JD.timeStr(r.h-sq); //昏
    this.rts[i].ch = JD.timeStr(r.h-r.c-0.5); //光照时间,timeStr()内部+0.5,所以这里补上-0.5
    this.rts[i].sj = JD.timeStr(r.j-r.s-0.5); //昼长
   }
   r = SZJ.Mt(jd+i+sq); //月亮
   c=int2(r.s-sq+0.5)-jd;  if(c>=0&&c<n) this.rts[c].Ms = JD.timeStr(r.s-sq);
   c=int2(r.z-sq+0.5)-jd;  if(c>=0&&c<n) this.rts[c].Mz = JD.timeStr(r.z-sq);
   c=int2(r.j-sq+0.5)-jd;  if(c>=0&&c<n) this.rts[c].Mj = JD.timeStr(r.j-sq);
  }
  this.rts.dn = n;
 }
};



//========太阳月亮计算类=============

function sun_moon(){
 this.calc=function(T,L,fa,high){ //sun_moon类的成员函数。参数:T是力学时,站点经纬L,fa,海拔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); //真恒星时(不考虑非多项式部分)
  var z=new Array();

  //=======月亮========
  //月亮黄道坐标
  XL.M_coord(T,z,-1,-1,-1); //月球坐标
  z[0]  = 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 = rad2mrad(this.gst - L - z[0]); //得到此刻天体时角
  if( this.mShiJ>Math.PI ) this.mShiJ -= pi2;

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

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

  //月亮地平坐标
  ZB.llrConv (z, Math.PI/2-fa );    //转到地平坐标(只改经纬度)
  z[0] = 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]  = 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 = rad2mrad(this.gst - L - z[0]); //得到此刻天体时角
  if( this.sShiJ>Math.PI ) this.sShiJ -= 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] = 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]; //方位角,高度角

  //=======其它========
  //时差计算
  t=T/10; var t2=t*t,t3=t2*t,t4=t3*t,t5=t4*t;
  var Lon = ( 1753469512 + 6283319653318*t + 529674*t2 + 432*t3 - 1124*t4 - 9*t5 + 630 * Math.cos(6+3*t) )/1000000000 + Math.PI - 20.5/rad; //修正了光行差的太阳平黄经
  Lon = rad2mrad( Lon - (this.sCJ-this.dL*Math.cos(this.E)) ); //(修正了光行差的平黄经)-(不含dL*cos(E)的视赤经)
  if(Lon>Math.PI) Lon-=pi2; //得到时差,单位是弧度
  this.sc  = Lon/pi2;   //时差(单位:日)

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

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

  //中心食计算
  if( Math.abs(rad2rrad(this.mCJ-this.sCJ))<50/180*Math.PI ){
   ZB.line_earth( this.mCJ,this.mCW,this.mR, this.sCJ,this.sCW,this.sR*cs_AU );
   this.zx_J = rad2rrad(this.gst-ZB.le_J);
   this.zx_W = ZB.le_W; //无解返回值是100
  } else this.zx_J=this.zx_W=100;
 };
 this.toHTML=function(fs){
  var s = '<table width="100%" cellspacing=1 cellpadding=0 bgcolor="#FFC0C0">';

  s += '<tr><td bgcolor=white align=center>';
  s += '平太阳 ' + JD.timeStr(msc.pty) + ' 真太阳 <font color=red>' + JD.timeStr(msc.zty) + '</font><br>';
  s += '时差 ' + m2fm(msc.sc*86400,2,1) + " 月亮被照亮 " + (msc.mIll*100).toFixed(2)+'% ';
  s += '</td></tr>';

  s += '<tr><td bgcolor=white><center><pre style="margin-top: 0; margin-bottom: 0"><font color=blue><b>表一       月亮            太阳</b></font>\r\n';
  s += '视黄经 ' + rad2str(msc.mHJ,0) +'  '+ rad2str(msc.sHJ,0) + '\r\n';
  s += '视黄纬 ' + rad2str(msc.mHW,0) +'  '+ rad2str(msc.sHW,0) + '\r\n';
  s += '视赤经 ' + rad2str(msc.mCJ,1) +'  '+ rad2str(msc.sCJ,1) + '\r\n';
  s += '视赤纬 ' + rad2str(msc.mCW,0) +'  '+ rad2str(msc.sCW,0) + '\r\n';
  s += '距离     ' + msc.mR.toFixed(0)  +'千米          '+ msc.sR.toFixed(6)+'AU'+'\r\n';
  s += '</pre></center></td></tr>';

  s += '<tr><td bgcolor=white><center><pre style="margin-top: 0; margin-bottom: 0"><font color=blue><b>表二       月亮            太阳</b></font>\r\n';
  s += '方位角 ' + rad2str(msc.mPJ,0) +'  '+ rad2str(msc.sPJ,0) + '\r\n';
  s += '高度角 ' + rad2str(msc.mPW,0) +'  '+ rad2str(msc.sPW,0) + '\r\n';
  s += '时角   ' + rad2str(msc.mShiJ,0)+'  '+rad2str(msc.sShiJ,0)+'\r\n';
  s += '视半径(观测点) ' + m2fm(msc.mRad,2,0) +'     '+ m2fm(msc.sRad,2,0)+'\r\n';
  s += '</pre></center></td></tr>';

  if(fs){
   s += '<tr><td bgcolor=white align=center>';
   s += '力学时 ' +JD.setFromJD_str(msc.T+J2000);
   s += ' ΔT=' + (msc.dt*86400).toFixed(1) +'秒<br>';
   s += '黄经章 '+(msc.dL/pi2*360*3600).toFixed(2) +'" ';
   s += '交角章 '+(msc.dE/pi2*360*3600).toFixed(2) +'" ';
   s += 'ε='+trim(rad2str(msc.E,0));
   s += '</td></tr>';
  }
  s += '</table>';
  return s;
 };
}


//====================================
var ysPL={ //月食快速计算器
 lineT:function(G, v,u, r, n){//已知t1时刻星体位置、速度,求x*x+y*y=r*r时,t的值
  var b=G.y*v-G.x*u, A=u*u+v*v, B=u*b, C=b*b-r*r*v*v, D=B*B-A*C;
  if(D<0) return 0;
  D=Math.sqrt(D); if(!n) D=-D;
  return G.t+((-B+D)/A-G.x)/v;
 },
 lecXY:function(jd,re){//日月黄经纬差转为日面中心直角坐标(用于月食)
  var T=jd/36525, zm=new Array(), zs=new Array();

  //=======太阳月亮黄道坐标========
  XL.E_coord(T,zs,-1,-1,-1);   //地球坐标
  zs[0]  = rad2mrad(zs[0]+Math.PI+ZB.gxc_sunLon(T));  zs[1]  =-zs[1] + ZB.gxc_sunLat(T); //补上太阳光行差
  XL.M_coord(T,zm,-1,-1,-1); //月球坐标
  zm[0]  = rad2mrad( zm[0]+ZB.gxc_moonLon(T) );  zm[1] += ZB.gxc_moonLat(T);  //补上月球光行差就可以了

  //=======视半径=======
  re.e_mRad = 358473400/zm[2]; //月亮地心视半径(角秒)
  re.eShadow = (cs_rEarA/zm[2]*rad-(959.63-8.794)/zs[2] )*51/50; //地本影在月球向径处的半径(角秒),式中51/50是大气厚度补偿
  re.eShadow2= (cs_rEarA/zm[2]*rad+(959.63+8.794)/zs[2] )*51/50; //地半影在月球向径处的半径(角秒),式中51/50是大气厚度补偿

  re.x = rad2rrad(zm[0]+Math.PI-zs[0]) * Math.cos((zm[1]-zs[1])/2);
  re.y = zm[1]+zs[1];
  re.mr= re.e_mRad/rad,  re.er=re.eShadow/rad, re.Er=re.eShadow2/rad;
  re.t = jd;
 },
 lecMax:function(jd){ //月食的食甚计算(jd为近朔的力学时,误差几天不要紧)
  this.lT=new Array();
  for(var i=0;i<7;i++) this.lT[i]=0; //分别是:食甚,初亏,复圆,半影食始,半影食终,食既,生光

  jd = XL.MS_aLon_t2( Math.floor((jd-4)/29.5306)*Math.PI*2 +Math.PI)*36525; //低精度的朔(误差10分钟),与食甚相差10分钟左右

  var g=new Object(), G=new Object(), u,v;

  //求极值(平均误差数秒)
  u = -18461 * Math.sin(0.057109+0.23089571958*jd)*0.23090/rad; //月日黄纬速度差
  v = (XL.M_v(jd/36525)-XL.E_v(jd/36525))/36525; //月日黄经速度差
  this.lecXY(jd,G);
  jd -= (G.y*u+G.x*v)/(u*u+v*v); //极值时间

  //精密求极值
  var dt=60/86400;
  this.lecXY(jd,G); this.lecXY(jd+dt,g); //精密差分得速度,再求食甚
  u = (g.y-G.y)/dt;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -