地球儀上でISS(国際宇宙ステーション)の位置を表示するプログラム(その5)
public double tjdCalc(Dtime a) //Tjdの計算
{
int jm = a.Month;
int jy = a.Year;
if (a.Month < 3)
{
jy = a.Year - 1;
jm += 12;
}
double jd = (int)(365.25 * jy) + (int)(jy / 400) - (int)(jy / 100)
+ (int)(30.59 * (jm - 2)) + a.Day + 1721088.5
+ (double)a.Hour / 24 + (double)a.Minute / 1440 + (double)a.Second / 86400;
double tjd = jd - 2440000.5;
return tjd;
}
private void orbital_sphere() //平面地図に軌道を表示する
{
keido = keido - 1;
xl = mx;
if (mb2 == true)
{
mx = System.Windows.Forms.Cursor.Position.X;
if (mb == false)
{
xl = mx;
mb = true;
}
}
int dx = xl - mx;
if (Math.Abs(dx) > 360)
dx = 0;
keido = keido + dx;
if (keido >= 360)
keido -= 360;
if (keido < 0)
keido += 360;
int rkeido = keido - 90;
if (rkeido > 180)
rkeido -= 360;
string rkeidoDirection = "E";
if (rkeido < 0)
{
rkeidoDirection = "W";
rkeido *= -1;
}
this.label2.Text = rkeido.ToString() + rkeidoDirection;
DateTime pDateJ = DateTime.Now; //現地日時表示
this.label1.Text = pDateJ.ToString();
DateTime crnt1 = DateTime.UtcNow; //現在日時をTJDへ
Dtime crnt2;
crnt2.Year = crnt1.Year;
crnt2.Month = crnt1.Month;
crnt2.Day = crnt1.Day;
crnt2.Hour = crnt1.Hour;
crnt2.Minute = crnt1.Minute;
crnt2.Second = crnt1.Second;
double tjdCurrent = tjdCalc(crnt2);
Bitmap canvas = new Bitmap(bmp3); //軌道計算
Graphics g = Graphics.FromImage(canvas);
Pen p = new Pen(Color.FromArgb(128, Color.Red), 1);
Font fnt = new Font("MS UI Gothic", 9);
int iff = 120;
int[] xll = new int[iff + 1];
int[] yl = new int[iff + 1];
double[] hsa = new double[iff + 1];
for (int i = 0; i < iff + 1; i++)
{
//グリニッジ平均恒星時計算
double tg = 24 * (0.671262 + 1.0027379094 * (tjdCurrent + (double)(iff - i) / 60 / 24));
tg = tg % 24;
double tl = tg + keido / 15;
if (tl > 24)
tl -= 24;
//真近点離角計算
double fai = ((tjdCurrent + (double)(iff - i) / 60 / 24 - t1.tjdep)
* t1.mm * 2 * Math.PI + t1.mk / 180 * Math.PI) % (Math.PI * 2);
double eec = fai + t1.ec * Math.Sin(fai);
double ek, de;
do
{
ek = fai + t1.ec * Math.Sin(eec);
de = Math.Abs(eec - ek);
eec = ek;
}
while (de > 0.000000000001);
double tanvk = Math.Sqrt(1 - t1.ec * t1.ec) * Math.Sin(ek) / (Math.Cos(ek) - t1.ec);
double vk = Math.Atan(tanvk);
double vkj = Math.Cos(ek) - t1.ec;
if (vkj < 0)
vk = vk + Math.PI;
//軌道位置計算
double tt = 24 * 3600 / t1.mm; //公転周期
double ar = (6.67384E-11 * 5.972E+24 * tt * tt / 4 / Math.PI / Math.PI);
ar = Math.Pow(ar, (double)1 / (double)3); //軌道長半径
double rk = ar * (1 - t1.ec * Math.Cos(ek));
double xk = rk * Math.Cos(vk);
double yk = rk * Math.Sin(vk);
//地心赤道直交座標変換
double xs = xk * t1.sx1 - yk * t1.sx2;
double ys = xk * t1.sy1 - yk * t1.sy2;
double zs = xk * t1.sz1 + yk * t1.sz2;
//G系地心直交座標変換
tg = tg / 24 * 2 * Math.PI;
double xg = xs * Math.Cos(tg) + ys * Math.Sin(tg);
double yg = ys * Math.Cos(tg) - xs * Math.Sin(tg);
double zg = zs;
//G系地心直交座標から経度・緯度及び楕円体高変換
double skeido = Math.Atan(yg / xg);
if (xg < 0)
skeido = skeido + Math.PI;
string LongitudeDirection = "E";
double skeidox = skeido;
if (skeido > Math.PI)
{
skeido = 2 * Math.PI - skeido;
skeidox = -skeido;
LongitudeDirection = "W";
}
if (skeido < 0)
{
skeidox = skeido;
skeido *= -1;
LongitudeDirection = "W";
}
double pg = Math.Sqrt(xg * xg + yg * yg);
double sido0 = Math.Atan(zg / pg);
double ds, sido, n;
double ag = 6377397.155;
double e2 = 0.006674372230614;
do
{
n = ag / Math.Sqrt(1 - e2 * e2 * Math.Sin(sido0) * Math.Sin(sido0));
sido = Math.Atan(zg / (pg - e2 * e2 * n * Math.Cos(sido0)));
ds = sido - sido0;
sido0 = sido;
}
while (ds > 0.000000000001);
string LatitudeDirection = "N";
double sidoy = sido;
if (sido < 0)
{
LatitudeDirection = "S";
sido *= -1;
}
double hs = pg / Math.Cos(sido);
skeido = skeido / Math.PI * 180;
sido = sido / Math.PI * 180;
//表示する
xll[i] = (int)((double)canvas.Width / 2 * (1 + skeidox / Math.PI));
yl[i] = (int)((double)canvas.Height / 2 * (1 - 2 * sidoy / Math.PI));
hsa[i] = hs / n;
hs -= n;
hs /= 1000;
int rl = 4;
if (i == iff)
{
p = new Pen(Color.FromArgb(255, Color.AntiqueWhite), 2);
rl = 6;
int cxl = xll[i];
int cyl = yl[i];
if (cxl > h + h - 180)
cxl = h + h - 180;
g.DrawString("LAT=" + sido.ToString("###") + LatitudeDirection
+ ",LON=" + skeido.ToString("###") + LongitudeDirection
+ ",ALT=" + hs.ToString("###KM"), fnt, Brushes.Coral, cxl, cyl + 5);
}
g.DrawEllipse(p, xll[i] - rl / 2, yl[i] - rl / 2, rl, rl);
}
fnt.Dispose();
g.Dispose();
this.pictureBox7.Image = canvas;
Bitmap sphereBmp = new Bitmap(h, h);
sphereBmp = sphere(xll, yl, hsa, iff);
this.pictureBox9.Image = sphereBmp;
}
次の記事へ続く。