/* * 1.0 code. */ import java.awt.*; import java.applet.Applet; /* * This version is slow but works in Netscape. It handles collisions * between the "Earth" and the spacecraft. "sun" is used to refer to the * central body, whatever it is (the Earth in this case). * Now includes restart button, a spacecraft with orientation, and * commands to rotate it and to fire its rockets. * Now includes double buffering to smooth out the image display. * Now shows flames while you are firing your rockets. * Now includes fuel limits and a fuel gauge. * Awards a coded magic number to those who succeed. * * Paul Francis, ANU. Last update 12/3/01 */ public class Assignment3 extends Applet implements Runnable { private static final int RADIUS = 5; int xcen = 0; int ycen = 0; int xint = 0; int yint = 0; int x2int = 0; int y2int = 0; int fuel0 = 100; int fuel = fuel0; // Set up starting positions, velocities and masses. double msun = 5.976E24; double xpos = 0.0E0; double ypos = 7400000.0E0; double xvel = 7400.0E0; double yvel = 0.0E0; double theta2 = 0.0; double time = 0.0; double r2 = 3.0E7; double v2 = Math.sqrt(6.67E-11*msun/r2); double x2,y2,xv2,yv2; double theta = 0.0; double xnorm = 0.0; double ynorm = 0.0; double relsep = 1.0E10; double relvel = 1.0E10; // scale determines the field of view double scale = 270000.0; // Tinker with timestep, fps or subloop to change speed. double timestep = 50.0; int fps = 20; double dfps = (double) fps; int subloop = 2; double dsubloop = (double) subloop; double velocity = 0.0; double r = 0.0; double rsun = 6400000.0; int delay; Thread animatorThread; boolean frozen = false; boolean collide = false; boolean fire = false; boolean fuelleft = true; boolean validate = false; boolean onceonly = true; int squareSize = 20; boolean fillColumnTop = true; Dimension offDimension; Image offImage; Graphics offGraphics; public void init() { String str; //How many milliseconds between frames? str = getParameter("fps"); try { if (str != null) { fps = Integer.parseInt(str); } } catch (Exception e) {} delay = (fps > 0) ? (1000 / fps) : 100; } public void start() { if (frozen) { //Do nothing. The user has requested that we //stop changing the image. } else { //Start animating! if (animatorThread == null) { animatorThread = new Thread(this); } animatorThread.start(); } } public void stop() { //Stop the animating thread. animatorThread = null; //Get rid of the objects necessary for double buffering. offGraphics = null; offImage = null; } public boolean mouseDown(Event e, int x, int y) { xcen = getSize().width/2; ycen = getSize().height/2; // Four buttons at the top of the screen. if (x > 0 & x < xcen/2+1 & y > 0 & y < 31){ theta = theta - 15.0; } else if (x > xcen/2 & x < xcen + 1 & y > 0 & y < 31){ theta = theta + 15.0; } else if (x > xcen & x < 3*xcen/2 + 1 & y > 0 & y < 31){ if (fuelleft){ xvel = xvel + 100.0*Math.sin(theta*3.141592/180.0); yvel = yvel + 100.0*Math.cos(theta*3.141592/180.0); fire = true; fuel = fuel - 1; if (fuel < 1){ fuelleft = false; } } } else if (x > 3*xcen/2 & x < 2*xcen+1 & y > 0 & y < 31){ xpos = 0.0E0; ypos = 7400000.0E0; xvel = 7400.0E0; yvel = 0.0E0; r = 0.0; theta2 = 0.0; time = 0.0; fire = false; theta = 0.0; fuelleft = true; fuel = fuel0; if (collide) { collide = false; } if (frozen) { frozen = false; start(); } } else { if (frozen) { frozen = false; if (collide) { animatorThread = null; } else { start(); } } else { frozen = true; animatorThread = null; } } return true; } public void run() { double G = 6.67E-11; double xtemp = 0.0; double ytemp = 0.0; double ax = 0.0; double ay = 0.0; //Just to be nice, lower this thread's priority //so it can't interfere with other processing going on. Thread.currentThread().setPriority(Thread.MIN_PRIORITY); //Remember the starting time. long startTime = System.currentTimeMillis(); //This is the animation loop. while (Thread.currentThread() == animatorThread) { //Calculate the position and speed of the target object time = time + timestep*dsubloop; theta2 = theta2 + timestep*dsubloop*v2/r2; x2 = Math.sin(theta2)*r2; y2 = Math.cos(theta2)*r2; xv2 = Math.cos(theta2)*v2; yv2 = Math.sin(theta2)*(-1.0*v2); relsep = Math.sqrt((xpos-x2)*(xpos-x2)+(ypos-y2)*(ypos-y2)); relvel = Math.sqrt((xvel-xv2)*(xvel-xv2)+(yvel-yv2)*(yvel-yv2)); xnorm = x2/scale; ynorm = y2/scale; x2int = xcen + (int) xnorm; y2int = ycen + (int) ynorm; // Now calculate the spacecraft position. // Several n-body integration steps per display step. // Uses mid-point integration method. for (int i = 0; i < subloop; i++){ xtemp = xpos + 0.5*xvel*timestep; ytemp = ypos + 0.5*yvel*timestep; r = Math.sqrt(xpos*xpos + ypos*ypos); ax = -0.5*timestep*xtemp*G*msun/(r*r*r); ay = -0.5*timestep*ytemp*G*msun/(r*r*r); velocity = Math.sqrt(xvel*xvel+yvel*yvel); xvel = xvel + ax; yvel = yvel + ay; xpos = xpos + xvel*timestep; ypos = ypos + yvel*timestep; xvel = xvel + ax; yvel = yvel + ay; xnorm = xpos/scale; ynorm = ypos/scale; xint = xcen + (int) xnorm; yint = ycen + (int) ynorm; } // Check for collisions with the planet or target. if (r < rsun){ frozen = true; collide = true; repaint(); stop(); } else if (relsep < 5.0E6 & relvel < 1000.0){ frozen = true; validate = true; repaint(); stop(); } else { //Display it. repaint(); } //Delay depending on how far we are behind. try { startTime += delay; Thread.sleep(Math.max(0, startTime-System.currentTimeMillis())); } catch (InterruptedException e) { break; } } } public void paint(Graphics g) { update(g); } public void update(Graphics g) { Dimension d = size(); int i, itemp; int sunrad, ftemp; int RADIUS = 5; int[] xPoints ; int[] yPoints ; xPoints = new int[3]; yPoints = new int[3]; double rnormsun = rsun/scale; double temp; double l =15.0; double m = 7.0; double phi = 150.0; sunrad = (int) rnormsun; xcen = getSize().width/2; ycen = getSize().height/2; //Create the offscreen graphics context, if no good one exists. if ( (offGraphics == null) || (d.width != offDimension.width) || (d.height != offDimension.height) ) { offDimension = d; offImage = createImage(d.width, d.height); offGraphics = offImage.getGraphics(); } //Erase the previous image. offGraphics.setColor(getBackground()); offGraphics.fillRect(0, 0, d.width, d.height); offGraphics.setColor(Color.black); // Set up plotting panel. offGraphics.setColor(Color.black); offGraphics.fillRect(0, 30, getSize().width - 1, getSize().height); offGraphics.setColor(Color.red); offGraphics.drawRect(0, 30, getSize().width - 1, getSize().height); offGraphics.setColor(Color.green); offGraphics.fillOval(xcen-sunrad,ycen-sunrad, 2*sunrad, 2*sunrad); //Print out velocity, time and distance in nice units. String svel = String.valueOf(velocity/1000.0); StringBuffer sbvel = new StringBuffer(30); String srad = String.valueOf((r-rsun)/1000.0); StringBuffer sbrad = new StringBuffer(30); String stime = String.valueOf(time/3600.0); StringBuffer sbtime = new StringBuffer(30); String srsep = String.valueOf(relsep/1000.0); StringBuffer sbrsep = new StringBuffer(40); String srvel = String.valueOf(relvel/1000.0); StringBuffer sbrvel = new StringBuffer(40); int dotpos = svel.lastIndexOf("."); sbvel.append("Velocity = "); for (i = 0; i