/*************************
EclipseDemoApplet7
Runs on Netscape 4.5 or newer , and Internet Explorer 5.5 or newer (as of Jan 2002).
Animation is double buffered and time controlled by a continuous running thread.
Allows user to enter date (UT, day, month, year) or set to current day, increment forward or back, run forward or back in time. Display shows orbit of the Moon (in three dimensions), with Moon located along with direction of Sun (from Earth), and lines of nodes of the Moon. Scroll bars on bottom and right allow user to rotate the graphic display to see from any angle.
Also displays day of Full Moon and New Moon along with days of eclipse seasons.
(Calculations for location of Moon and Sun are based on algorithms from Astronomical Formula for Calculators, 4th ed. Jean Meeus, Willmann-Bell. inc.Richmond VA, 1988)
C. Hartley January 20, 2002
**************************/
public class EclipseDemoApplet7 extends Applet implements Runnable
{
int GRAPH_WIDTH =605 ;//set graphPanel size
int GRAPH_HEIGHT = 275 ;
/************************
Things to get graphics working
*************************/
public Image Buffer;
public Graphics gBuffer;// graphics buffer
private Color grayBlue = new Color(150,150,190);
private Color darkOrange = new Color(200, 150, 0);
private Color darkGreen = new Color(0, 160,0);
private Scrollbar phiBar;//to get angles
private Scrollbar thetaBar;
/*************************
Things to service Choice menus to get months
**************************/
private String[] monthStrings = { "January", "February", "March",
"April", "May", "June", "July", "August", "September", "October", "November",
"December" };
public Choice monthList = new Choice();// month Choice menu thingy.
/*************************
TextFields etc.
**************************/
public TextField UTText;
public TextField dayText;
public TextField yearText;
private Color tanColor;//which is really light blue.
public DecimalFormat twoDigits = new DecimalFormat("00.00");
//to format output to TextFields
/*************************
To keep track and set dates
**************************/
public Calendar today;//a date and date related things
public dates date; //one of my classes. Handles double UT (time), int day, int monthNumber, int year, and months month[] which has month[].name, and month[].maxDays. months is one of my classes with string name and int maxDays.
public double jdn;// julian day number
public double deltaT = 0;
public double incrementT = .125;
public boolean step = false;
private String[] incrementString = {"15 minute","1 hour", "3
hour", "12 hours", "1 day", "3 day", "10 day"};
public Choice incrementList = new Choice();
public double[] incrementValue = { 0.01041666666, 0.041666666666,
0.125, 0.5, 1.0, 3.0, 10.0};
/***************************
To set views with Radio Buttons (CheckBoxGroup)
***************************/
CheckboxGroup cbg = new CheckboxGroup(); //build a group
public Checkbox threeDViewButton = new Checkbox("3D view
of orbit", cbg, true);
public Checkbox nodesViewButton = new Checkbox("Sky view of Nodes",
cbg, false);
/**********************
And a Thread
***********************/
private volatile Thread runner;
int delay = 200;
/************************
Variables to animate the moon
*************************/
private vector rc = new vector((int)(GRAPH_WIDTH/2),(int)(GRAPH_HEIGHT/2-20),0);
private double radiusMoon = 90;//radius of orbit of the Moon
private vector r1 = new vector (0,0,0);
private vector r2 = new vector (0,0,0);
private vector rt = new vector (0,0,0);
private vector rotX = new vector(0,0,0);//when dotted with vector
gives the x components of the rotated vector; a function of theta and phi
private vector rotY = new vector(0,0,0);//Y version of rotX
private vector incX = new vector (0,0,0);// when dotted with
vector inclines it by rotation about z axis
private vector incY = new vector (0,0,0); //y version
private vector incZ = new vector (0,0,0); // z version
private vector ihat= new vector (radiusMoon,0,0); //x axis
private vector jhat= new vector(0,-radiusMoon,0); //y axis
private vector khat= new vector(0,0,radiusMoon); // z axis
private double T ;//time (centuries since 1900)
private double theta = 0.0;
private double phi = 0.0;
private double incline = -5.16*Math.PI/180; //inclination of
orbit moon
private double omega = 0.0; //long of ascending node.
/************************
For the error messages
*************************/
public String message;
/*************************
Constructor for the class
**************************/
public void init()
{
Calendar today = Calendar.getInstance();// get the current date.
int day =today.get(today.DAY_OF_MONTH);//separate out day, year,
monthNumber, and UT.
int year = today.get(today.YEAR);
int monthNumber= today.get(today.MONTH);
double UT = ((double)today.get(today.MINUTE))/60 + (double)today.get(
today.HOUR_OF_DAY);
date = new dates(year, monthNumber, day, UT);//make it the date
until further notice
jdn= date.toJulianDay();
T = (jdn-2415020)/36525;
/***********************************
Set up the Applet for Layout
***********************************/
setLayout( new BorderLayout());// for the applet
setBackground(Color.white);
tanColor = new Color(215,225,255);
/*******************************
Create the topPanel for the top of the window
********************************/
Panel topPanel = new Panel();//for top of the page
topPanel.setLayout( new BorderLayout());
topPanel.setBackground(tanColor);
/*********************************
Create a datePanel to get time and date information to program
**********************************/
Panel datePanel= new Panel();//for date information and buttons
datePanel.setLayout( new FlowLayout());
datePanel.setBackground(tanColor);
UTText=new TextField(5);//TextField
UTText.setBackground(Color.white);
UTText.setText(twoDigits.format(date.UT));
Label UTLabel = new Label("Time");
datePanel.add(UTLabel);
datePanel.add(UTText);
dayText=new TextField( 3);//TextField
dayText.setBackground(Color.white);
dayText.setText(Integer.toString(date.day));
Label dayLabel = new Label("Day");
datePanel.add(dayLabel);
datePanel.add(dayText);
monthList.addItem("January");
monthList.addItem("February");
monthList.addItem("March");
monthList.addItem("April");
monthList.addItem("May");
monthList.addItem("June");
monthList.addItem("July");
monthList.addItem("August");
monthList.addItem("September");
monthList.addItem("October");
monthList.addItem("November");
monthList.addItem("December");
monthList.select(date.monthNumber);
monthList.setBackground(Color.white);
datePanel.add(monthList);
yearText=new TextField( 5);//TextField
yearText.setBackground(Color.white);
yearText.setText(Integer.toString(year));
datePanel.add(yearText);
ButtonHandler buttonHandler = new ButtonHandler();
Button todayButton = new Button("Set to Today");//Button to set
date to today
todayButton.setBackground(Color.white);
todayButton.addActionListener(buttonHandler);
datePanel.add(todayButton);
Button calculateButton = new Button("to Date Entered");//Button
to produce calculation using date
calculateButton.setBackground(Color.white);
calculateButton.addActionListener(buttonHandler);
datePanel.add(calculateButton);
topPanel.add(datePanel, BorderLayout.NORTH);
/*******************************
Create a time increment panel to get time increments into the program
********************************/
Panel timeIncPanel = new Panel();//to hold Buttons to control
increment of time
timeIncPanel.setLayout( new FlowLayout());
timeIncPanel.setBackground(tanColor);
/***************************
Add RadioButtons to control the view
*****************************/
threeDViewButton.setBackground(tanColor);
nodesViewButton.setBackground(tanColor);
timeIncPanel.add(threeDViewButton);
timeIncPanel.add(nodesViewButton);
incrementList.setBackground(Color.white);
incrementList.addItem("15 minutes");
incrementList.addItem("1 hour");
incrementList.addItem("3 hours");
incrementList.addItem("12 hours");
incrementList.addItem("1 day");
incrementList.addItem("3 days");
incrementList.addItem("10 days");
incrementList.select(2);
ChoiceListener listener = new ChoiceListener();
incrementList.addItemListener(listener);
timeIncPanel.add(incrementList);
Button backwardsButton = new Button("<<");
backwardsButton.setBackground(Color.white);
backwardsButton.addActionListener(buttonHandler);
timeIncPanel.add(backwardsButton);
Button stepBackButton = new Button("|<");
stepBackButton.setBackground(Color.white);
stepBackButton.addActionListener(buttonHandler);
timeIncPanel.add(stepBackButton);
Button pauseButton = new Button(" || ");
pauseButton.setBackground(Color.white);
pauseButton.addActionListener(buttonHandler);
timeIncPanel.add(pauseButton);
Button stepForeButton = new Button(">|");
stepForeButton.setBackground(Color.white);
stepForeButton.addActionListener(buttonHandler);
timeIncPanel.add(stepForeButton);
Button forwardButton = new Button(">>");
forwardButton.setBackground(Color.white);
forwardButton.addActionListener(buttonHandler);
timeIncPanel.add(forwardButton);
topPanel.add(timeIncPanel, BorderLayout.SOUTH);
Panel bottomPanel = new Panel();//to hold topPanel and the thetaScrollBar
bottomPanel.setLayout( new BorderLayout());
bottomPanel.add(topPanel, BorderLayout.SOUTH);
/*****************************
Create Scroll Bars
*******************************/
phiBar = new Scrollbar(Scrollbar.HORIZONTAL,0,10, -180, 190);
bottomPanel.add(phiBar, BorderLayout.NORTH);
thetaBar = new Scrollbar(Scrollbar.VERTICAL, 0,10,-90,100);
add(thetaBar, BorderLayout.EAST);
add(bottomPanel,BorderLayout.SOUTH);
/********************************
Creat the graphics buffer etc.
*********************************/
Buffer= createImage(GRAPH_WIDTH, GRAPH_HEIGHT);
gBuffer = Buffer.getGraphics();
}// closes init()
/********************************
To service the thread
*********************************/
public void start()
{
if (runner ==null)
{
runner = new Thread(this);
runner.start();
}
}
public void stop()
{
runner = null;
}
public void run()
{
Thread thisThread = Thread.currentThread();
while (runner ==thisThread)
{
repaint();
try
{
Thread.sleep(delay);
}
catch (InterruptedException e)
{
// nothing
}
}
}
/******************************
Extends JPanel to draw graphics on it. Creates a Buffer Image and draws
on it then sends that to the JPanel when drawing is all done.
*******************************/
public void paint(Graphics g)
{
super.paint(g);
gBuffer.setColor(Color.white);//clear the Buffer so I can
draw on it;
gBuffer.fillRect(0,0,GRAPH_WIDTH,GRAPH_HEIGHT);
jdn = jdn + deltaT;//update date data
T = (jdn-2415020)/36525;
dates date2 = new dates();
date2 = date2.JulianToDate(jdn);
gBuffer.setColor(Color.blue);
gBuffer.drawString( twoDigits.format(date2.UT) + " hours
UT " + Integer.toString(date2.day) + " " + date2.month[date2.monthNumber].name
+ " " + Integer.toString(date2.year),10, 195);
//calc long of ascending node of Moon & orient orbit of Moon
double dr = Math.PI/180;
omega = (259.183 - 1934.142*T + 0.002078*T*T)*dr;
//Calculate the longitude of the Sun
double M = (358.476 + 35999.04975*T - 0.000150*T*T)*dr;//
M
double C = (1.919 - 0.004789*T - 0.000014*T*T)*dr*Math.sin(M);
double longSun = (279.697 + 36000.769*T + 0.00030258*T*T
)*dr;
double lambdaSun = longSun + C;
//Calculate longitude of the Moon on the orbit
double Mprime = (296.105+477198.8491*T+0.009192*T*T)*dr;//mean
anomaly M'
double D = (350.737+445267.1142*T-0.001436*T*T)*dr;//mean
elongation D
double F = 11.2509 + 483202.0251*T - 0.003211*T*T; //mean
distance to ascending node
double lambdaMoon = (270.4342 + 481267.8831*T - 0.001133*T*T
+ 6.2875*Math.sin(Mprime)
+ 1.2740*Math.sin(2*D - Mprime)
+ 0.6583*Math.sin(2*D)
+ 0.2136*Math.sin(2*Mprime)
-0.1856*Math.sin(M)
-0.1143*Math.sin(2*F)
+0.0588*Math.sin(2*D-2*Mprime)
+0.0572*Math.sin(2*D-M-Mprime)
+0.0533*Math.sin(2*D+Mprime)
+0.0459*Math.sin(2*D-M)
+0.0410*Math.sin(Mprime-M)
-0.0347*Math.sin(D)
-0.0305*Math.sin(M+Mprime)
)*dr;// longitude of Moon
//Check for New and Full Moons
double diff = (lambdaSun-lambdaMoon)/dr;
diff = diff%360;
if (diff<-180)
diff = diff + 360;
if (diff >180)
diff = diff -360;
gBuffer.setColor(Color.red);
if (Math.abs(diff)<6.5)
gBuffer.drawString("New Moon Day", 10,210);
if (Math.abs(diff)>173.5)
gBuffer.drawString("Full Moon Day", 10, 210);
//Check for Eclipse Season
diff = (lambdaSun-omega)/dr;
diff = diff%360;
if (diff<-180)
diff = diff + 360;
if (diff >180)
diff = diff -360;
gBuffer.setColor(Color.red);
if (Math.abs(diff)<15)
gBuffer.drawString("Eclipse Season", 10, 225);
if (Math.abs(diff) >175)
gBuffer.drawString("Eclipse Season", 10, 225);
/********************************
Do one of the three views
********************************/
//see page 211 of Deitel and Deitel for this multi-selection structure,
switch/case
int choice = 0;
if (threeDViewButton.getState())
choice = 1;
else if (nodesViewButton.getState())
choice = 2;
else System.out.println("Got wrong cbg button group selected
problem.");
switch(choice)
{
case 1:
/*******************************
to animate the planet
********************************/
gBuffer.setColor(Color.black);
//get angles from ScrollBars to tip display
theta = (thetaBar.getValue())*dr;
phi = (phiBar.getValue())*dr;
//set up rotation matrices
rotX.x = Math.cos(phi);
rotX.y = -Math.sin(phi)*Math.sin(theta);
rotX.z = Math.sin(phi)*Math.cos(theta);
rotY.x = 0;
rotY.y = Math.cos(theta);
rotY.z = Math.sin(theta);
// inclines the orbit by the angle incline with nodes at angle omega
incX.x = Math.cos(incline)*Math.cos(omega);
incX.y = Math.sin(omega);
incX.z = Math.cos(omega)*Math.sin(incline);
incY.x = -Math.sin(omega)*Math.cos(incline);
incY.y = Math.cos(omega);
incY.z = Math.sin(omega)*Math.sin(incline);
incZ.x = -Math.sin(incline);
incZ.y = 0;
incZ.z = Math.cos(incline);
//draw the coordinate axes once they have been rotated; i, j, k for
x, y, z axes
rt.x = ihat.dot(rotX);
rt.y = ihat.dot(rotY);
r2 = rc.adder(rt);
r1 = rc.subber(rt);
gBuffer.drawLine((int)r1.x, (int)r1.y, (int)r2.x,(int)r2.y);
rt.x = jhat.dot(rotX);
rt.y = jhat.dot(rotY);
r2 = rc.adder(rt);
r1 = rc.subber(rt);
gBuffer.drawLine((int)r1.x, (int)r1.y, (int)r2.x,
(int)r2.y);
gBuffer.setColor(Color.red);
rt.x = khat.dot(rotX);
rt.y = khat.dot(rotY);
r2 = rc.adder(rt);
r1 = rc.subber(rt);
gBuffer.drawLine((int)r1.x, (int)r1.y, (int)r2.x,
(int)r2.y);
/********************************************
Draw a circle on the screen for orbit of Moon
*********************************************/
gBuffer.setColor(darkGreen);
//draw line of nodes
r1.x = 0; //unrotated x compents of point on circle
r1.y = radiusMoon;//y component too
r1.z = 0; //z component
rt.x = r1.dot(incX); //incline by angle
rt.y = r1.dot(incY);
rt.z = r1.dot(incZ);
r1.x = rt.dot(rotX); //rotate it
r1.y = rt.dot(rotY);
r2 = rc.subber(r1);
r1 = r1.adder(rc);//add vector to center
gBuffer.drawLine((int)r2.x,(int)r2.y, (int)r1.x,
(int)r1.y);
gBuffer.drawString("Line of Nodes", (int)r1.x, (int)r1.y);
//Draw the orbit of the Moon
double gamma; //polar angle in circle
gBuffer.setColor(Color.blue);
for (gamma = 0; gamma<6.3; gamma = gamma+0.06)
{
r2.x = radiusMoon*Math.sin(gamma); //unrotated
x compents of point on circle
r2.y = radiusMoon*Math.cos(gamma);//y component
too
r2.z = 0; //z component
rt.x = r2.dot(incX); //incline by angle
rt.y = r2.dot(incY);
rt.z = r2.dot(incZ);
r2.x = rt.dot(rotX); //rotate it
r2.y = rt.dot(rotY);
r2 = r2.adder(rc);//add vector to center
gBuffer.drawLine((int)r1.x,(int)r1.y, (int)r2.x,
(int)r2.y);
r1.setEqual(r2);// save current point for
start of next line
}
//Place the Moon on the orbit
r2.x = radiusMoon*Math.sin(lambdaMoon- omega); //unrotated
x compents of point on circle
r2.y = radiusMoon*Math.cos(lambdaMoon - omega);//y
component too
r2.z = 0; //z component
rt.x = r2.dot(incX); //incline by angle
rt.y = r2.dot(incY);
rt.z = r2.dot(incZ);
r2.x = rt.dot(rotX); //rotate it
r2.y = rt.dot(rotY);
r2 = r2.adder(rc);//add vector to center
gBuffer.setColor(grayBlue);
gBuffer.fillOval((int)r2.x-5, (int)r2.y-5, 10, 10);
gBuffer.drawString("Moon", (int)r2.x, (int)r2.y
- 7);
//Place line to Sun
gBuffer.setColor(Color.yellow);
//unrotated longitude
rt.x = (radiusMoon+25)*Math.sin(lambdaSun );
rt.y = (radiusMoon+25)*Math.cos(lambdaSun );
rt.z = 0;
r2.x = rt.dot(rotX); //rotate it
r2.y = rt.dot(rotY);
r2 = r2.adder(rc);//add vector to center
gBuffer.setColor(darkOrange);
gBuffer.drawLine((int)rc.x,(int)rc.y, (int)r2.x,
(int)r2.y);// draw line to Sun
gBuffer.drawString("To Sun", (int)r2.x,(int)r2.y);
break;//ends this case
/********************************\
Draw two boxes to display objects near ascending node
*********************************/
case 2:
int boxCornerX = 2;
int boxCornerY = 7;
int boxWidth = 580;
int boxHeight = 75;
int boxCenterX = boxCornerX +boxWidth /2;
int boxCenterY = boxCornerY +boxHeight/2;
int boxSeparation = 20;
gBuffer.setColor(Color.black);
gBuffer.drawRect(boxCornerX , boxCornerY, boxWidth,
boxHeight);
gBuffer.drawLine(boxCornerX, boxCenterY,boxCornerX
+ boxWidth, boxCenterY);
gBuffer.drawLine(boxCenterX, boxCornerY,boxCenterX,
boxCornerY + boxHeight);
int boxCorner2Y = boxCornerY + boxSeparation + boxHeight;
int boxCenter2Y = boxCenterY + boxSeparation + boxHeight;
gBuffer.drawRect(boxCornerX , boxCorner2Y, boxWidth,
boxHeight);
gBuffer.drawLine(boxCornerX, boxCenter2Y,boxCornerX
+ boxWidth, boxCenter2Y);
gBuffer.drawLine(boxCenterX, boxCorner2Y,boxCenterX,
boxCorner2Y + boxHeight);
/***************************
Set up sizes of moon and Sun (planets) and shodow of Earth
****************************/
double boxWidthDegrees = 15;
double boxScale = boxWidth/2/boxWidthDegrees;
int planetSize = (int)(0.5*boxScale);
int planetOffset = (int)(0.25*boxScale);
int shadowSize = (int)(0.5*3.67*boxScale);
int shadowOffset = (int)(0.25*3.67*boxScale);
/********************************
Check location of Sun and plot it in box
*********************************/
double diffSun = ((lambdaSun- omega)/dr)%360;
if (diffSun<-180)
diffSun = diffSun + 360;
if (diffSun>180)
diffSun = diffSun -360;
// place Sun in ascending node box
if (Math.abs(diffSun)<boxWidthDegrees)
{
double x = -boxScale*diffSun + (double)boxCenterX;
gBuffer.setColor(darkOrange);
gBuffer.drawOval((int)x - planetOffset, boxCenterY
- planetOffset, planetSize, planetSize);
gBuffer.fillOval((int)x - planetOffset, boxCenterY
- planetOffset, planetSize, planetSize);
//place shadow of Earth in descending node box
gBuffer.setColor(grayBlue);
gBuffer.drawOval((int)x -shadowOffset, boxCenter2Y
- shadowOffset, shadowSize,shadowSize);
}
//Place Sun in descending node box
if (Math.abs(diffSun)>180 - boxWidthDegrees)
{
diff = diffSun + 180;
if (diff>360)
diff = diff -360;
if (diff < -180) diff = diff + 360;
if (diff > 180) diff = diff -360;
double x = -boxScale*diff + (double)boxCenterX;
double y = boxCenter2Y;
gBuffer.setColor(darkOrange);
gBuffer.fillOval((int)x - planetOffset, (int)y
- planetOffset, planetSize, planetSize);
gBuffer.drawOval((int)x - planetOffset, (int)y
- planetOffset, planetSize, planetSize);
//place shadow of Earth in ascending node box
gBuffer.setColor(grayBlue);
gBuffer.drawOval((int)x -shadowOffset, boxCenterY
- shadowOffset, shadowSize,shadowSize);
}
/************************************
Check to see how close Moon is to ascending node
and plot location of Moon on little map
*************************************/
double diffMoon = ((lambdaMoon- omega)/dr)%360;
if (diffMoon<-180)
diffMoon = diffMoon + 360;
if (diffMoon>180)
diffMoon = diffMoon -360;
// place Moon in ascending node box
if (Math.abs(diffMoon)<boxWidthDegrees)
{
double x = -boxScale*diffMoon + (double)boxCenterX;
double y = -boxScale*5.16*Math.sin(diffMoon*dr)
+ boxCenterY;
gBuffer.setColor(grayBlue);
gBuffer.fillOval((int)x - planetOffset, (int)y
- planetOffset, planetSize, planetSize);
gBuffer.drawOval((int)x - planetOffset, (int)y
- planetOffset, planetSize, planetSize);
}
// place Moon in descending node box
if (Math.abs(diffMoon)>180 - boxWidthDegrees)
{
diff = diffMoon + 180;
if (diff>360)
diff = diff -360;
if (diff < -180) diff = diff + 360;
if (diff > 180) diff = diff -360;
double x = -boxScale*diff + (double)boxCenterX;
double y = boxScale*5.16*Math.sin(diff*dr)
+ boxCenter2Y;
gBuffer.setColor(grayBlue);
gBuffer.fillOval((int)x - planetOffset, (int)y
- planetOffset, planetSize, planetSize);
gBuffer.drawOval((int)x - planetOffset, (int)y
- planetOffset, planetSize, planetSize);
}
} //end of switch structure
if (step)
{
deltaT=0;
step = false;
}
//put the image we just drew on the JPanel
g.drawImage(Buffer,0,0,this);
}//closes the paint routine
//to keep update from doing other than paint
public void update(Graphics g)
{
paint(g);
}
/*******************************
Catches events and performs actions
********************************/
public class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String actionCommand= e.getActionCommand();
if(actionCommand.equals("to Date Entered"))
{
try
{ double x;
date.UT = Double.valueOf(UTText.getText()).doubleValue();
x= Double.valueOf(dayText.getText()).doubleValue();
date.day = (int)x;
x= Double.valueOf(yearText.getText()).doubleValue();
date.year = (int)x;
date.monthNumber =monthList.getSelectedIndex();
date.monthCheck();
jdn= date.toJulianDay();
T = (jdn-2415020)/36525;
}
catch(NumberFormatException nfe)
{
message = "Day and Year must be positive integers.
Time is a decimal number.";
BaseFrame dialog= new BaseFrame("ERROR MESSAGE");
dialog.setVisible(true);
}
catch(ArithmeticException ae)
{
message = ae.toString();
BaseFrame dialog= new BaseFrame("ERROR MESSAGE");
dialog.setVisible(true);
}
}
else if (actionCommand.equals("Set to Today"))
{
Calendar today = Calendar.getInstance();
date.day =today.get(today.DAY_OF_MONTH);
date.year = today.get(today.YEAR);
date.monthNumber= today.get(today.MONTH);
date.UT = ((double)today.get(today.MINUTE))/60 +
(double)today.get( today.HOUR_OF_DAY);
UTText.setText(twoDigits.format(date.UT));
dayText.setText(Integer.toString(date.day));
yearText.setText(Integer.toString(date.year));
monthList.select(date.monthNumber);
jdn= date.toJulianDay();
T = (jdn-2415020)/36525;
}
else if (actionCommand.equals("<<"))
{
deltaT = -incrementT;
}
else if (actionCommand.equals("|<"))
{
deltaT = -incrementT;
step = true;
}
else if (actionCommand.equals(" || "))
{
deltaT = 0;
}
else if (actionCommand.equals(">|"))
{
deltaT = incrementT;
step = true;
}
else if (actionCommand.equals(">>"))
{
deltaT = incrementT;
}
else
System.out.println("Error in button interface.");
}
} //closes ButtonHandler
/*******************************
a Listener for the ScrollBar (well actually it is Choice menu
********************************/
public class ChoiceListener implements ItemListener
{
public void itemStateChanged(ItemEvent ie)
{
incrementT = incrementValue[incrementList.getSelectedIndex()];
deltaT = 0;
}
}
/************************************
Class of dates to keep track of UT (time), day, month, year. Calculates
Julian day number, and from JDN calculates a dates. Uses class months.
*************************************/
public class dates
{
public int year;
public int monthNumber;
public int day;
public double UT;
public months[] month;
public dates()
{
}
public dates(int newYear, int newMonth, int newDay, double newUT)
{
year = newYear;
monthNumber = newMonth;
day = newDay;
UT = newUT;
month = new months[12];
month[0] = new months("January", 31);
month[1]= new months("February", 29);
month[2]= new months("March",31);
month[3]= new months("April", 30);
month[4]= new months( "May",31);
month[5]= new months("June",30);
month[6]= new months("July", 31);
month[7]= new months("August", 31);
month[8]= new months("September", 30);
month[9]= new months("October", 31);
month[10]= new months("November", 30);
month[11]= new months("December", 31);
}
//Converts a dates to a Julian Day Number
public double toJulianDay()
{
double d = (double)day;
d = d + UT/24;
double m = (double)monthNumber;
m= m + 1;
double y = (double)year;
if((m == 1)||(m ==2))
{
y = y - 1;
m = m + 12;
}
double B=0;
if ((y>1582)||((y==1582)&&(m>10))||((y==1582)&&(m==10)&&(d>15)))
{
double A = inty(y/100);
B = 2 - A + inty(A/4);// Gregorian calendar only!!!
}
double jd = inty(365.25*(y + 4716))+ inty(30.6001*(m+1))+
d + B - 1524.5;
return jd;
}
//From a Julian Day Number calculates a dates
public dates JulianToDate(double jd)
{
jd = jd+ 0.5;
double Z = inty(jd);
double F = jd - Z;
double A = Z;
if (Z>=2299161)
{
double alpha = inty((Z -1867216.25)/36524.25);
A = Z +1 + alpha -inty(alpha/4);
}
double B = A + 1524;
double C = inty((B - 122.1)/365.25);
double D = inty(365.25*C);
double E = inty((B - D)/30.6001);
double d = B - D - inty(30.6001*E) + F;
day = (int)d;
double UT = (d-day)*24;
double m = E-1;
if (E>13) m = E -13;
monthNumber = (int)m;
double y = C - 4716;
if (m<=2) y = C - 4715;
year = (int)y;
dates date = new dates(year, monthNumber - 1, day, UT);
return date;
}
// I need integer value function and I can't find one; made my own.
public double inty(double x)
{
double d;
if(x>0)
d = Math.floor(x);
else
d = Math.ceil(x);
return d;
}
//Check to see if month for a given dates has correct number of days
public void monthCheck() throws DateMismatchException
{
String monthProblem = month[monthNumber].name + " of "
+ Integer.toString(year) + " does not have that many days.";
if(day>month[monthNumber].maxDays)
throw new DateMismatchException (monthProblem);
if(day<=0)
throw new DateMismatchException (" Days must be
a positive integer.");
if (year<=0)
throw new DateMismatchException(" Year must be a
positive integer.");
if ((UT<0)||(UT>24))
throw new DateMismatchException(" UT must be positive
and less than 24.");
if ((monthNumber == 1)&&(day == 29))
{
if (year%4!=0)
throw new DateMismatchException(monthProblem);
if (year >1582)
if ((year%4==0)&&(year%100==0)&&(year%400!=0))
throw new DateMismatchException(monthProblem);
}
}
}
/****************************
Check to see if days entered in TextField is a number
****************************/
public class DateMismatchException extends ArithmeticException
{
public DateMismatchException()
{
super ("Problem with days of the month.");
}
public DateMismatchException( String message)
{
super(message);
}
}
/*****************************
Class of months, used by dates class; has names of months, and maximum
number of days for each month.
*****************************/
public class months
{
public String name;
public int maxDays;
public months(String newName, int newmaxDays)
{
name = newName;
maxDays = newmaxDays;
}
}
/***************************
Class of vector; the usual 3 D vectors with a few methods
****************************/
public class vector
{
public double x;//x, y & z component of vectors
public double y;
public double z;
public vector(double xin,double yin,double zin)
{
x=xin;
y=yin;
z=zin;
}
//So I can print out the components of a vector for diagnostic reasons.
public void coordinatePrinter(String s)
{
System.out.println(s +" Coordinates ( " +(double)Math.round(100*x)/100
+ "," + (double)Math.round(100*y)/100 + " " + (double)Math.round(100*z)/100+"
)");
}
//So I can add one vector to another.
public vector adder(vector V)
{
vector Sum = new vector(x + V.x, y + V.y, z + V.z);
return Sum;
}
//Subtracts vector V from this vector
public vector subber(vector V)
{
vector Sub = new vector(x - V.x, y - V.y, z - V.z);
return Sub;
}
//Rotates this vector by the angle theta (given in radians)
public vector rotateBy(double theta)
{
vector A = new vector(0,0,0);
A.x = x*Math.cos(theta) +y*Math.sin(theta);
A.y = -x*Math.sin(theta) +y*Math.cos(theta);
A.z = z;
return A;
}
//Produces the dot product between this and vector V.
public double dot(vector V)
{
double a = x*V.x + y*V.y + z*V.z;
return a;
}
//makes components of this vector equal to components of the V vector.
public void setEqual(vector V)
{
x = V.x;
y = V.y;
z = V.z;
}
}//closes vector class
/********************************
To construct a throw up Frame to display error messages
*********************************/
public class BaseFrame extends Frame
{
public BaseFrame(String title)
{
super(title);
Label label = new Label(message);
setSize(600,100);
setLayout(new BorderLayout());
add(label, BorderLayout.CENTER);
setLocation(20,150);
WindowDestroyer myListener = new WindowDestroyer();
addWindowListener(myListener);
}
public class WindowDestroyer extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
setVisible(false);
}
}
}//closes BaseFrame class
}//closes the applet
All text and JAVA program copyright ©2002 by C. Hartley, Department of Physics, Hartwick College, Oneonta, New York, unless otherwise noted.