/******************************************************************************
* 星空ウォッチング(プラネタリウム) *
* by「菊池さん」 *
* Copyright(C) 2001 Kikuchi-san's workshop. All rights reserved. *
*****************************************************************************/
import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import java.io.*;
public class SkyWatching extends Applet implements SkyData {
SkyStatus status; //ステータスパネル
SkyControls controls; //コントロールパネル
SkyCanvas canvas; //描画キャンパス
public void init() {
//HTML文書よりパラメータの内容を受け取る。
canvas.R = Integer.parseInt(getParameter("size")); //画面サイズ
canvas.cityName = getParameter("city"); //観測地名
setSize(canvas.R+canvas.offsetX*2,canvas.R/2+canvas.offsetZ*2+canvas.msize+60); //サイズ設定
//背景・描画色とレイアウト設定
setBackground(new Color(0,0,192));
setForeground(new Color(0,0,0));
setLayout(new BorderLayout());
canvas = new SkyCanvas();
add("Center", canvas);
add("North", status = new SkyStatus(canvas));
add("South", controls = new SkyControls(canvas));
}
public void destroy() {
remove(status);
remove(controls);
remove(canvas);
}
public void start() {
status.setEnabled(true);
controls.setEnabled(true);
}
public void stop() {
status.setEnabled(false);
controls.setEnabled(false);
}
public void processEvent(AWTEvent evt) {
if (evt.getID() == Event.WINDOW_DESTROY) { System.exit(0); }
}
public String getAppletInfo() {
return "星空ウォッチング(プラネタリウム)\nby「菊池さん」 ";
}
} //end of SkyWatching
// 描画キャンパス
class SkyCanvas extends Canvas {
SkyData data; //観測地、星データ
SkyStatus status; //ステータスパネル
static int cityNo,DIR,SPD;
static String EW,LNG,NS,LAT,TD,dirN;
//初期値設定
static int R;
static String cityName;
static int offsetX = 10; //横両サイドのりしろ
static int offsetZ = 20; //縦両サイドのりしろ
static int msize = 12; //表示文字のサイズ(px)
//日付取得
static Calendar now = Calendar.getInstance();
static int year = now.get(Calendar.YEAR);
static int mon = now.get(Calendar.MONTH)+1;
static int day = now.get(Calendar.DAY_OF_MONTH);
static int hour = now.get(Calendar.HOUR_OF_DAY);
static int min = now.get(Calendar.MINUTE);
static String DATE = year+"/"+mon+"/"+day; //日付
static String HOUR = (min <10)? hour+":0"+min : hour+":"+min; //時刻
String direction[] = {"西","北","東"}; //方角バー
//判定フラグ
boolean bool_All = false; //再描画
boolean bool_Star = false; //星名表示
boolean bool_Seiza = false; //星座表示
boolean bool_Trace = false; //航跡
static boolean city_flag = false; //緯経度指定
//描画部品定義
public void paintSky(Graphics g) { //半天球
g.setColor(Color.black);
g.fillArc(offsetX,offsetZ,R,R,0,180);
}
public void paintStar(Graphics g) { //星
int ls,le,Xls,Zls,Xle,Zle;
double ANG = 0;
double WID = 0;
double starAZ,starEL;
double pol[] = new double[3]; //極座標値
double xyz[] = new double[3]; //xyz座標値
for (int i = 0; i < data.star.length; i++) {
int SMs[] = new int[21]; //星の光度(大きさ)
Color SCs[] = new Color[21]; //星のスペクトル(色)
double Xs[] = new double[21]; //星のX座標値
double Zs[] = new double[21]; //星のZ座標値
String NMs[] = new String[21]; //星名
for (int j = 2; j < data.star[i].length; j++) {
//星データ1行抽出
SkyCalculate.starData[0] = data.star[i][j][0];
SkyCalculate.starData[1] = data.star[i][j][1];
SkyCalculate.starData[2] = data.star[i][j][2];
SkyCalculate.starData[3] = data.star[i][j][3];
NMs[j-2] = data.star[i][j][4];
//日付時刻、観測地緯経度、時差計算
SkyCalculate.setDATA();
//星の光度、色、赤経、赤緯計算
SkyCalculate.calc_Star();
//経過ユリウス世紀の計算
SkyCalculate.T = SkyCalculate.calc_T();
//地方恒星時の計算
SkyCalculate.Theta = SkyCalculate.calc_Theta();
//現在時刻の方位角、高度計算
starAZ = SkyCalculate.calc_AZ(); //方位角
starEL = SkyCalculate.calc_EL(); //高度
//距離、方位角、高度初期値
pol[0] = R/2.0;
pol[1] = 90.0 - starAZ;
pol[2] = 90.0 - starEL;
//地平線下はプロットしない
if (starEL < 0.0) continue;
//cos、sin値による象限判定と方角のプロット判断
double cosAZ = Math.cos(SkyCalculate.pai * starAZ);
double sinAZ = Math.sin(SkyCalculate.pai * starAZ);
if (DIR == 0) { if (cosAZ < 0.0) continue; }
else if (DIR == 1) { pol[1] += 90.0; if (sinAZ < 0.0) continue; }
else if (DIR == 2) { pol[1] += 180.0; if (cosAZ > 0.0) continue; }
else if (DIR == 3) { pol[1] += 270.0; if (sinAZ > 0.0) continue; }
//極座標 -> 直交座標変換
SkyCalculate.AZEL2XYZ(pol,xyz);
//星座を構成する星を配列に記録
SMs[j-2] = SkyCalculate.SM;
SCs[j-2] = SkyCalculate.SC;
Xs[j-2] = xyz[0];
Zs[j-2] = xyz[2];
}
if (bool_Seiza) {
g.setColor(Color.blue);
for (int k = 0; k < data.star[i][1].length; k +=2) {
ls = Integer.parseInt(data.star[i][1][k]);
le = Integer.parseInt(data.star[i][1][k+1]);
//プロットの判断
if (Xs[ls] == 0.0 || Xs[le] == 0.0) continue;
Xls = (int)Math.round(Xs[ls]);
Zls = (int)Math.round(Zs[ls]);
Xle = (int)Math.round(Xs[le]);
Zle = (int)Math.round(Zs[le]);
g.drawLine(Xls,-Zls,Xle,-Zle);
}
g.setColor(Color.pink);
ls = Integer.parseInt(data.star[i][0][1]);
//プロットの判断
if (Xs[ls] != 0.0) {
Xls = (int)Xs[ls]+5;
Zls = (int)Zs[ls]+5;
g.drawString(data.star[i][0][0],Xls,-Zls);
}
}
for (int k = 0; k < data.star[i].length-2; k++) {
//プロットの判断
if (Xs[k] == 0.0) continue;
g.setColor(SCs[k]);
Xls = (int)Math.round(Xs[k]);
Zls = (int)Math.round(Zs[k]);
g.fillOval(Xls,-Zls,SMs[k],SMs[k]);
if (bool_Star && !NMs[k].equals("")) {
g.setColor(Color.lightGray);
g.drawString(NMs[k],Xls,-Zls-3);
}
}
}
}
public void paintBar(Graphics g) { //方角バー
g.setColor(new Color(230,230,230));
g.fillRoundRect(offsetX,R/2+offsetZ,R,msize,10,5);
g.setColor(Color.red);
g.drawString(direction[0],offsetX,R/2+offsetZ+msize-2);
g.drawString(direction[1],R/2+offsetX-msize/2,R/2+offsetZ+msize-2);
g.drawString(direction[2],R+offsetX-msize,R/2+offsetZ+msize-2);
}
//描画
public void paint(Graphics g) {
g.setColor(Color.white);
g.drawString(DATE,20,20);
g.drawString(HOUR,80,20);
switch(DIR) {
case 0: dirN = "北"; break;
case 1: dirN = "東"; break;
case 2: dirN = "南"; break;
case 3: dirN = "西"; break;
}
g.drawString("方角: "+dirN,130,20);
g.drawString("観測地",20,32);
g.setColor(Color.cyan);
g.drawString(data.city[cityNo][0],70,32);
g.setColor(Color.white);
g.drawString("( "+EW+" "+LNG,20,44);
g.drawString(NS+" "+LAT+" ",90,44);
g.drawString("時差 "+TD+" )",150,44);
paintSky(g);
paintBar(g);
g.translate(R/2+offsetX,R/2+offsetZ);
paintStar(g);
}
//再描画
public void redraw(boolean bool_All) {
this.bool_All = bool_All;
repaint();
}
} //end of SkyCanvas
// ステータスパネル
class SkyStatus extends Panel implements ActionListener, ItemListener {
SkyData data; //観測地、星データ
SkyCanvas canvas; //描画キャンパス
SkyCalculate calculate; //描画キャンパス
Choice choice_Direction = new Choice();
Choice choice_City = new Choice();
Choice choice_Sign_lng = new Choice();
Choice choice_Sign_lat = new Choice();
Button button_help = new Button("ヘルプ");
Button button_redraw = new Button("再描画");
TextField textfield_lng = new TextField(10);
TextField textfield_lat = new TextField(10);
TextField textfield_date = new TextField(10);
TextField textfield_hour = new TextField(10);
Frame window = new SkyHelp("星空ウォッチング(プラネタリウム)ヘルプ");
public SkyStatus(SkyCanvas canvas) {
this.canvas = canvas;
window.setSize(500, 150); //Windowのサイズ決め
window.setLocation(180, 100); //Windowの表示位置決め
//テキストフィールド初期値セット
textfield_date.setText(canvas.DATE);
textfield_hour.setText(canvas.HOUR);
//初期画面ではボタン操作不可にする
choice_Sign_lng.setEnabled(false);
choice_Sign_lat.setEnabled(false);
textfield_lng.setEnabled(false);
textfield_lat.setEnabled(false);
//ステータスパネル作成
setLayout(new GridLayout(2,1));
setBackground(new Color(192,192,192));
//上段
add(new Label("方角:",Label.RIGHT));
choice_Direction.addItem("北");
choice_Direction.addItem("東");
choice_Direction.addItem("南");
choice_Direction.addItem("西");
add(choice_Direction); choice_Direction.addItemListener(this);
add(new Label("経度:",Label.RIGHT));
choice_Sign_lng.addItem("E");
choice_Sign_lng.addItem("W");
add(choice_Sign_lng); choice_Sign_lng.addItemListener(this);
add(textfield_lng);
add(new Label("日付:",Label.RIGHT));
add(textfield_date);
add(button_help); button_help.addActionListener(this);
//下段
add(new Label("観測地:",Label.RIGHT));
for (int i = 0; i < data.city.length; i++) choice_City.addItem(data.city[i][0]);
add(choice_City); choice_City.addItemListener(this);
for (int i = 0; i < data.city.length; i++) {
if (choice_City.getItem(i).equals(canvas.cityName)) {
choice_City.select(i);
canvas.cityNo = i;
canvas.EW = data.city[i][1]; //東/西経
canvas.LNG = data.city[i][2]; //観測地経度
canvas.NS = data.city[i][3]; //北/南緯
canvas.LAT = data.city[i][4]; //観測地緯度
canvas.TD = data.city[i][5]; //観測地時差
textfield_lng.setText(canvas.LNG);
textfield_lat.setText(canvas.LAT);
}
}
add(new Label("緯度:",Label.RIGHT));
choice_Sign_lat.addItem("N");
choice_Sign_lat.addItem("S");
add(choice_Sign_lat); choice_Sign_lat.addItemListener(this);
add(textfield_lat);
add(new Label("時刻:",Label.RIGHT));
add(textfield_hour);
button_redraw.setBackground(new Color(0,139,139));
button_redraw.setForeground(Color.white);
add(button_redraw); button_redraw.addActionListener(this);
}
//ボタンイベント
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource(); //イベント種類
String arg = evt.getActionCommand(); //イベント文字列
if (src == button_redraw) {
canvas.LNG = textfield_lng.getText().trim();
canvas.LAT = textfield_lat.getText().trim();
canvas.DATE = textfield_date.getText().trim();
canvas.HOUR = textfield_hour.getText().trim();
SkyCalculate.setDATA();
canvas.redraw(arg.equals("再描画"));
}
if (src == button_help) {
if (arg.equals("ヘルプ")) {
button_help.setLabel("閉じる");
window.show();
}
if (arg.equals("閉じる")) {
button_help.setLabel("ヘルプ");
window.dispose();
}
}
} //end of actionPerformed
//ポップアップメニューイベント
public void itemStateChanged(ItemEvent evt) {
Object src = evt.getSource();
String arg = (String)evt.getItem();
if (src == choice_Direction) {
if (arg.equals("北")) {
canvas.DIR = 0;
canvas.direction[0]="西"; canvas.direction[1]="北"; canvas.direction[2]="東";
} else if (arg.equals("東")){
canvas.DIR = 1;
canvas.direction[0]="北"; canvas.direction[1]="東"; canvas.direction[2]="南";
} else if (arg.equals("南")){
canvas.DIR = 2;
canvas.direction[0]="東"; canvas.direction[1]="南"; canvas.direction[2]="西";
} else if (arg.equals("西")){
canvas.DIR = 3;
canvas.direction[0]="南"; canvas.direction[1]="西"; canvas.direction[2]="北";
}
}
if (src == choice_City) {
for (int i = 0; i < data.city.length; i++) {
if (arg.equals(data.city[i][0])) {
choice_Sign_lng.setEnabled(false); //ボタン操作不可にする
choice_Sign_lat.setEnabled(false);
textfield_lng.setEnabled(false);
textfield_lat.setEnabled(false);
canvas.EW = data.city[i][1]; //規定値セット
canvas.NS = data.city[i][3];
canvas.TD = data.city[i][5];
for (int j = 0; j < 2; j++) { //EW選択値に表示切替
if (choice_Sign_lng.getItem(j).equals(canvas.EW)) choice_Sign_lng.select(j);
}
for (int j = 0; j < 2; j++) { //NS選択値に表示切替
if (choice_Sign_lat.getItem(j).equals(canvas.NS)) choice_Sign_lat.select(j);
}
textfield_lng.setText(data.city[i][2]);
textfield_lat.setText(data.city[i][4]);
canvas.cityNo = i;
canvas.city_flag=false;
if (arg.equals("緯経度指定")) {
canvas.city_flag = true;
choice_Sign_lng.setEnabled(true); //ボタン操作可にする
choice_Sign_lat.setEnabled(true);
textfield_lng.setEnabled(true);
textfield_lat.setEnabled(true);
canvas.EW = choice_Sign_lng.getSelectedItem(); //入力値セット
canvas.NS = choice_Sign_lat.getSelectedItem();
}
break;
}
}
}
if (src == choice_Sign_lng) {
if (arg.equals("E")) { canvas.EW="E"; }
else if (arg.equals("W")) { canvas.EW="W"; }
}
if (src == choice_Sign_lat) {
if (arg.equals("N")) { canvas.NS="N"; }
else if (arg.equals("S")) { canvas.NS="S"; }
}
} //end of itemStateChanged
} //end of SkyStatus
// コントロールパネル
class SkyControls extends Panel implements ActionListener, ItemListener {
SkyCanvas canvas; //描画キャンパス
Button button_Motion = new Button("日周運動開始");
Choice choice_Trace = new Choice();
Choice choice_Speed = new Choice();
Button button_Star = new Button("星名表示");
Button button_Seiza = new Button("星座表示");
Button button_Zoomin = new Button("+");
Button button_Zoomout = new Button("−");
public SkyControls(SkyCanvas canvas) {
this.canvas = canvas;
//コントロールパネル作成
setBackground(new Color(0,192,192));
add(button_Motion); button_Motion.addActionListener(this);
add(new Label("航跡:",Label.RIGHT));
choice_Trace.addItem("無");
choice_Trace.addItem("有");
add(choice_Trace); choice_Trace.addItemListener(this);
add(new Label("速度:",Label.RIGHT));
choice_Speed.addItem("普通");
choice_Speed.addItem("高速");
choice_Speed.addItem("低速");
add(choice_Speed); choice_Speed.addItemListener(this);
add(button_Star); button_Star.addActionListener(this);
add(button_Seiza); button_Seiza.addActionListener(this);
add(new Label("ズーム:",Label.RIGHT));
add(button_Zoomin); button_Zoomin.addActionListener(this);
add(button_Zoomout); button_Zoomout.addActionListener(this);
}
//ボタンイベント
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource(); //イベント種類
String arg = evt.getActionCommand(); //イベント文字列
if (src == button_Motion) {
if (arg.equals("日周運動開始")) {
button_Motion.setLabel("日周運動停止");
canvas.bool_Trace = true;
canvas.SPD = 1;
System.out.println("日周運動開始 pressed!");
}
if (arg.equals("日周運動停止")) {
button_Motion.setLabel("日周運動開始");
canvas.bool_Trace = false;
canvas.SPD = 0;
System.out.println("日周運動停止 pressed!");
}
}
if (src == button_Star) {
if (arg.equals("星名表示")) {
button_Star.setLabel("星名消去");
canvas.bool_Star = true;
choice_Trace.setEnabled(false); //航跡操作不可にする
choice_Trace.select(0); //航跡無しにリセット
canvas.repaint();
}
if (arg.equals("星名消去")) {
button_Star.setLabel("星名表示");
canvas.bool_Star = false;
if (!canvas.bool_Seiza) choice_Trace.setEnabled(true); //航跡操作可にする
canvas.repaint();
}
}
if (src == button_Seiza) {
if (arg.equals("星座表示")) {
button_Seiza.setLabel("星座消去");
canvas.bool_Seiza = true;
choice_Trace.setEnabled(false); //航跡操作不可にする
choice_Trace.select(0); //航跡無しにリセット
canvas.repaint();
}
if (arg.equals("星座消去")) {
button_Seiza.setLabel("星座表示");
canvas.bool_Seiza = false;
if (!canvas.bool_Star) choice_Trace.setEnabled(true); //航跡操作可にする
canvas.repaint();
}
}
if (src == button_Zoomin) {
canvas.R *=1.2;
canvas.repaint();
}
if (src == button_Zoomout) {
canvas.R /=1.2;
canvas.repaint();
}
} //end of actionPerformed
//ポップアップメニューイベント
public void itemStateChanged(ItemEvent evt) {
Object src = evt.getSource();
String arg = (String)evt.getItem();
if (src == choice_Trace) {
if (arg.equals("有")) {
canvas.bool_Trace = true;
System.out.println("航跡 "+arg+" selected!");
}
if (arg.equals("無")) {
canvas.bool_Trace = false;
System.out.println("航跡 "+arg+" selected!");
}
}
if (src == choice_Speed) {
System.out.println("速度 "+arg+" selected!");
}
} //end of itemStateChanged
} //end of SkyControls
// 計算ルーチン
class SkyCalculate implements SkyData {
//グローバル変数
static int YY,MM,DD,HH,MI,SS; //日付,時刻,時差
static double I; //時差
static double pai = Math.PI / 180.0; //角度->ラジアン変換定数
static double dT,Dn; //地球自転遅れ補正値(日),本日0時からの経過日数(0.xxx日)
static double K,T,Theta; //本日0時の経過ユリウス年,現在時刻の経過ユリウス世紀,地方恒星時
static double starLNG,starLAT,cityLNG,cityLAT; //星の赤経赤緯,観測地経度緯度
static int SM; //星の光度(大きさ)
static Color SC; //星のスペクトル(色)
static String starData[] = new String[5];
//作業変数
static int temp0,temp1,temp2;
static String tempS[] = new String[3];
//=========================================================================
// 日付時刻、観測地緯経度、時差計算
//=========================================================================
public static void setDATA() {
//日付
decode(SkyCanvas.DATE ,"/" ,tempS);
YY = Integer.parseInt(tempS[0].trim());
MM = Integer.parseInt(tempS[1].trim());
DD = Integer.parseInt(tempS[2].trim());
//時刻
decode(SkyCanvas.HOUR ,":" ,tempS);
HH = Integer.parseInt(tempS[0].trim());
MI = Integer.parseInt(tempS[1].trim());
SS = 0;
//観測地経度 → 数値変換
decode(SkyCanvas.LNG ,"°" ,tempS);
temp0 = Integer.parseInt(tempS[0].trim());
decode(tempS[1] ,"′" ,tempS);
temp1 = Integer.parseInt(tempS[0].trim());
if (SkyCanvas.EW.equals("W")) { temp0 = -temp0; temp1 = -temp1; }
cityLNG = dofun2num(temp0,temp1,0);
//観測地緯度 → 数値変換
decode(SkyCanvas.LAT ,"°" ,tempS);
temp0 = Integer.parseInt(tempS[0].trim());
decode(tempS[1] ,"′" ,tempS);
temp1 = Integer.parseInt(tempS[0].trim());
if (SkyCanvas.NS.equals("S")) { temp0 = -temp0; temp1 = -temp1; }
cityLAT = dofun2num(temp0,temp1,0);
//時差
decode(SkyCanvas.TD ,"." ,tempS);
temp0 = Integer.parseInt(tempS[0].trim());
temp1 = Integer.parseInt(tempS[1].trim());
if (temp1 < 9) I = temp0 + temp1 / 10.0;
else I = temp0 + temp1 / 100.0;
if (SkyCanvas.city_flag) { //緯経度入力の場合は経度から時差計算
I = cityLNG/15.0;
SkyCanvas.TD = String.valueOf(Math.round( I * 10.0 ) / 10.0);
}
} //end of setDATA
//=========================================================================
// 星の光度、色、赤経、赤緯計算
//=========================================================================
public static void calc_Star() {
//光度
decode(starData[0] ,"." ,tempS);
temp0 = Integer.parseInt(tempS[0].trim());
temp1 = Integer.parseInt(tempS[1].trim());
SM = (int)Math.round(temp0 + temp1 / 10.0);
if (SM > 90) SM = SM /100;
if (SM < 0) SM = 0;
SM = 6 - SM;
//色
if (starData[1].equals("O")) SC = Color.red;
else if (starData[1].equals("B")) SC = Color.cyan;
else if (starData[1].equals("A")) SC = Color.white;
else if (starData[1].equals("F")) SC = Color.yellow;
else if (starData[1].equals("G")) SC = Color.yellow;
else if (starData[1].equals("K")) SC = Color.yellow;
else if (starData[1].equals("M")) SC = Color.magenta;
//赤経
decode(starData[2] ," " ,tempS);
temp0 = Integer.parseInt(tempS[0].trim());
temp1 = Integer.parseInt(tempS[1].trim());
temp2 = Integer.parseInt(tempS[2].trim());
starLNG = dofun2num(temp0,temp1,temp2) * 15.0;
//赤緯
decode(starData[3] ," " ,tempS);
temp0 = Integer.parseInt(tempS[1].trim());
temp1 = Integer.parseInt(tempS[2].trim());
if (tempS[0].equals("-")) { temp0 = -temp0; temp1 = -temp1; }
starLAT = dofun2num(temp0,temp1,0);
}
//=========================================================================
//
//=========================================================================
public static void decode(String str, String delim ,String items[]) {
int i=0;
for (StringTokenizer st = new StringTokenizer(str,delim); st.hasMoreTokens();)
{ items[i] = st.nextToken(); i++; }
}
//=========================================================================
// 極座標系(距離、方位角、高度)から直交座標系(X、Y、Z)への変換
// 引数 .... 極座標値(距離、方位角、高度) p[0],p[1],p[2](角度単位°)
// 戻り値 .... 直交座標値(X、Y、Z) x[0],x[1],x[2]
//=========================================================================
public static void AZEL2XYZ(double p[],double x[]) {
x[2] = p[0] * Math.cos(pai * p[2]);
x[1] = p[0] * Math.sin(pai * p[2]);
x[0] = x[1] * Math.cos(pai * p[1]);
x[1] = x[1] * Math.sin(pai * p[1]);
}
//=========================================================================
// 直交座標の回転
// x[0,1,2]をbase軸(0 = x,1 = y, z = 2) の周りに p 回転させる。結果は xに戻す
//
//=========================================================================
public static void ROTXYZ(double xyz[],double p) {
double temp[] = new double[3];
temp[0] = Math.cos(p) * xyz[0] - Math.sin(p) * xyz[1];
temp[1] = Math.sin(p) * xyz[0] + Math.cos(p) * xyz[1];
xyz[0] = temp[0]; xyz[1] = temp[1];
}
//=========================================================================
// 経緯度:度分->経緯度:数値変換(dd°ff′bb″ -> xx.xxxx)
//=========================================================================
public static double dofun2num(int dd ,int ff ,int bb)
{ return dd+ff/60.0+bb/3600.0; }
//=========================================================================
// J2000.0(2000年1月1日力学時正午)から現在時刻までの経過ユリウス世紀の計算
// 引数 .... (2000+YY)年MM月DD日(標準時差:I) YY,MM,DD,I
// 戻り値 .... 現在時刻の経過ユリウス世紀(T年)
// .... 本日0時からの経過日数(0.xxx日) Dn
//=========================================================================
public static double calc_T() {
dT = ( 57.0 + 0.8 * (YY - 1990) ) / 86400.0; //地球自転遅れ補正値(日)
//時差I時間の観測地での(2000+YY)年MM月DD日地方時0時からの経過日数(K)の計算
int YYY = YY - 2000; int MMM = MM;
if(MMM < 3) { YYY -= 1; MMM += 12; }
K = 365.0*YYY + 30.0*MMM + DD - 33.5 - I/24.0;
K += Math.floor( 3.0*(MMM + 1.0) / 5.0 );
K += Math.floor( YYY / 4.0 );
//本日0時の経過ユリウス年
K = ( K + dT ) / 365.25;
//本日0時からの経過日数(0.xxx日)
Dn = HH/24.0 + MI/1440.0 + SS/86400.0;
//現在時刻の経過ユリウス世紀(=ユリウス年/100)
T = ( K + Dn/365.25 ) / 100.0;
return T;
}
//=========================================================================
// 経度cityLNGの観測地点で、日本時 Dnのときの恒星時Θ(Theta度)の計算
// 引数 .... 観測地点の経度(度) cityLNG
// .... J2000.0からのその日0時の経過ユリウス世紀 T
// .... 日本時によるその日0時からの経過日数(力学時)(0.xxx日) Dn
// 戻り値 .... 観測地点の恒星時Θ(度) Theta
//=========================================================================
public static double calc_Theta() {
Theta = 325.4606 + 36000.7700536*T + 0.0003879*T*T + 360.0*Dn + cityLNG;
return Theta;
}
//=========================================================================
// 経度cityLNGの地点の日本時 Dnにおける赤経、赤緯(度)の天体の方位角(AZ)計算
// 引数 .... 天体の赤経、赤緯(α,δ) starLNG,starLAT
// .... 観測地点の経度、緯度(度) cityLNG,cityLAT
// .... 観測地点で日本時 Dnのときの恒星時Θ(度) Theta
// 戻り値 .... 観測地点における天体の方位角(AZ)
//=========================================================================
public static double calc_AZ() {
double t,AZ0,AZ1,AZ;
t = Theta - starLNG; //経度cityLNGの観測地点の日本時Dn時の天体の時角
AZ0 =-Math.cos(pai * starLAT) * Math.sin(pai * t);
AZ1 = Math.sin(pai * starLAT) * Math.cos(pai * cityLAT);
AZ1 -= Math.cos(pai * starLAT) * Math.sin(pai * cityLAT) * Math.cos(pai * t);
AZ = Math.atan(AZ0 / AZ1) / pai;
if (AZ1 > 0 && AZ < 0) { AZ = 360 + AZ; } //分母がプラスのときは-90 +180°
AZ = ( Math.round(AZ * 10) ) / 10;
return AZ ;
}
//=========================================================================
// 経度cityLNGの地点の日本時 Dnにおける赤経、赤緯(度)の天体の高度(EL)計算
// 引数 .... 天体の赤経、赤緯(α,δ) starLNG,starLAT
// .... 観測地点の経度、緯度(度) cityLNG,cityLAT
// .... 観測地点で日本時 Dnのときの恒星時Θ(度) Theta
// 戻り値 .... 観測地点における天体の高度(EL)
//=========================================================================
public static double calc_EL() {
double t,EL;
t = Theta - starLNG; //経度cityLNGの観測地点の日本時Dn時の天体の時角
EL = Math.sin(pai * starLAT) * Math.sin(pai * cityLAT);
EL += Math.cos(pai * starLAT) * Math.cos(pai * cityLAT) * Math.cos(pai * t);
EL = Math.asin(EL) / pai;
EL += 0.0167 / Math.tan( pai * (EL + 8.6/(EL + 4.4)) ); // 大気差補正
EL = ( Math.round(EL * 10) ) / 10;
return EL ;
}
} //end of SkyCalculate
//=========================================================================
//
//=========================================================================
class SkyHelp extends Frame {
SkyHelp(String help) {
super(help);
setBackground(Color.white);
setForeground(Color.blue);
setFont(new Font("Dialog",Font.PLAIN,12));
}
public void paint(Graphics g) {
String msg ="ここに使用方法のヘルプを書く予定です。表示を消す時は「閉じる」を押して下さい。";
g.drawString(msg,10,40); //文字表示
}
} //end of SkyHelp