/* * ftjn.java - revised 17 Apr 05 - width 401, height 301 * @author jackord@kw.igs.net * restricted 3-body problem: * (1) locating equilibrium sites in the rotating frame using a color * plot of effective potential * (2) testing the stability of orbits at the Trojan and saddle point sites */ import java.applet.Applet; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class ftjn extends Applet implements ActionListener, Runnable { int kk=0; int first=0; // Declarations int x0, y0, imax; // Global double x1, x2, m1, m2, w, w2, dt; // variables String bs = "Plot"; Button bb = new Button(bs); Color col[]={ Color.blue, Color.cyan, Color.red, Color.yellow, Color.green, Color.magenta }; Choice ch=new Choice(); CheckboxGroup chg=new CheckboxGroup(); Checkbox[] chb=new Checkbox[2]; Thread tmr; public void init() { setLayout(new FlowLayout(FlowLayout.LEFT)); setBackground(new Color(211, 211, 211)); ch.addItem("M/m=9"); ch.addItem("M/m=19"); ch.addItem("M/m=29"); ch.addItem("M/m=99"); ch.addItem("Jupiter"); ch.addItem("Earth"); add(ch); add(bb); add(chb[0]=new Checkbox("Trojan", chg, true)); add(chb[1]=new Checkbox("Saddle", chg, false)); bb.addActionListener(this); ch.setBackground(getBackground()); chb[0].setBackground(getBackground()); chb[1].setBackground(getBackground()); } public void start() { if (tmr==null) { tmr=new Thread(this); tmr.setPriority(Thread.MIN_PRIORITY); tmr.start(); } } public void stop() { tmr=null; } public void run() { repaint(); } public void pause(int n) { try { Thread.sleep(n); } catch (InterruptedException e) { stop(); } } double f(double x) { // Force double r13, r23; r13=Math.pow((x-x1)*(x-x1), 1.5); r23=Math.pow((x-x2)*(x-x2), 1.5); return w2*(x-x0)+m1*(x1-x)/r13+m2*(x2-x)/r23; } public void orbit(double x, double y, Graphics g) { // Plot orbit double r13, r23, vx, vy, dvx, dvy; int xa, ya, xb, yb; r13=Math.pow((x-x1)*(x-x1)+(y-y0)*(y-y0), 1.5); r23=Math.pow((x-x2)*(x-x2)+(y-y0)*(y-y0), 1.5); dvx=(w2*(x-x0)-m1*(x-x1)/r13-m2*(x-x2)/r23)*dt; dvy=(w2*(y-y0)-m1*(y-y0)/r13-m2*(y-y0)/r23)*dt; vx=dvx/2; vy=dvy/2; xa=(int)(x); ya=(int)(y); for (int i=1; i<=imax; i=i+1) { // Feynman loop x=x+vx*dt; y=y+vy*dt; xb=(int)(x); yb=(int)(y); g.drawLine(xa, ya, xb, yb); xa=xb; ya=yb; // Plot r13=Math.pow((x-x1)*(x-x1)+(y-y0)*(y-y0), 1.5); r23=Math.pow((x-x2)*(x-x2)+(y-y0)*(y-y0), 1.5); dvx=(w2*(x-x0)-2*w*(vy+dvy/2)-m1*(x-x1)/r13-m2*(x-x2)/r23)*dt; dvy=(w2*(y-y0)+2*w*(vx+dvx/2)-m1*(y-y0)/r13-m2*(y-y0)/r23)*dt; vx=vx+dvx; vy=vy+dvy; if ((r13<2197)||(r23<729)) { i=imax; } // Crash } } public void paint(Graphics g) { // Main Program if (first==0) { // Screen layout bb.setBounds(5, 277, 40, 20); chb[0].setBounds(50, 277, 60, 20); chb[1].setBounds(115, 277, 60, 20); first=1; } double r1, r2, r13, r23, rr, d, e, f, h, u, x, y, xx, yy; int ii, xa, xb, ya, yb, jm, xm; double[] m=new double[6]; double[] c=new double[6]; double[] a=new double[3]; double[] b=new double[3]; m[0]=.1; m[1]=.05; m[2]=1./30.; m[3]=.01; m[4]=.001; m[5]=.000003; c[0]=.209; c[1]=.2116; c[2]=.2123; c[3]=.2137; c[4]=.21427; c[5]=.21429; x0=200; y0=150; d=140; w2=1/(d*d*d); w=Math.sqrt(w2); ii=ch.getSelectedIndex(); m2=m[ii]; m1=1-m2; x1=x0-m2*d; x2=x0+m1*d; // Site M and m a[0]=0; b[0]=x1-13; a[1]=x0; b[1]=x2-9; a[2]=x2+9; b[2]=400; xx=x1+d/2; yy=y0-d*Math.sqrt(3)/2; // Site Trojans g.setColor(Color.black); // Initial screen g.drawRect(0, 0, 400, 300); g.setColor(Color.gray); g.fillArc((int)(x1+.5)-13, y0-13, 27, 27, 0, 360); g.fillArc((int)(x2+.5)-9, y0-9, 19, 19, 0, 360); g.setColor(Color.black); g.drawArc((int)(x1+.5)-13, y0-13, 26, 26, 0, 360); g.drawArc((int)(x2+.5)-9, y0-9, 18, 18, 0, 360); if (kk>0) { long tt=System.currentTimeMillis(); int del=8; for (int i=1; i<=399; i=i+1) { // Scan the screen for (int j=1; j<=299; j=j+1) { rr=(i-x0)*(i-x0)+(j-y0)*(j-y0); r1=Math.sqrt((i-x1)*(i-x1)+(j-y0)*(j-y0)); r2=Math.sqrt((i-x2)*(i-x2)+(j-y0)*(j-y0)); if ((r1>13)&&(r2>9)) { u=w2*rr/2+m1/r1+m2/r2; // Effective potential g.setColor(col[(int)(c[ii]/u)%6]); g.drawLine(i, j, i, j); // Color pixel } } if ((tt+i*del)>System.currentTimeMillis()) { pause(10); } } g.setColor(Color.black); g.drawArc((int)(x1+.5)-13, y0-13, 26, 26, 0, 360); g.drawArc((int)(x2+.5)-9, y0-9, 18, 18, 0, 360); if (chb[0].getState()==true) { // Trojan site g.setColor(Color.white); g.drawLine((int)(x1), (int)(y0), (int)(x2), (int)(y0)); g.drawLine((int)(x1), (int)(y0), (int)(xx), (int)(yy)); g.drawLine((int)(x2), (int)(y0), (int)(xx), (int)(yy)); g.setColor(Color.black); pause(1500); dt=5; imax=(int)(32*Math.PI/w/dt); if(ii==5) { imax=10*imax; } x=xx; y=yy-d/400; orbit(x, y, g); } else { // Saddle points g.setColor(Color.white); g.drawLine(0, 150, 400, 150); xa=0; ya=0; dt=1; imax=(int)(8*Math.PI/w/dt); xm=400; jm=2; if (ii>3) { xm=180; jm=0; dt=5; imax=10*imax; if (ii==5) { dt=50; } } for (int i=0; i<=xm; i=i+1) { r13=Math.pow((i-x1)*(i-x1), 1.5); r23=Math.pow((i-x2)*(i-x2), 1.5); xb=i; yb=(int)(150.5+2E5*(w2*(x0-i)+m1*(i-x1)/r13+m2*(i-x2)/r23)); if ((i>0)&&(ya>0)&&(yb<300)) { g.drawLine(xa, ya, xb, yb); // Plot force } xa=xb; ya=yb; } g.setColor(Color.black); for (int j=0; j<=jm; j=j+1) { // Three saddle points e=a[j]; f=b[j]; // if ii<4 while ((f-e)>.001) { // Bisection algorithm h=(e+f)/2; if (f(h)<0) { e=h; } else { f=h; } } x=(e+f)/2; y=y0-d/400; orbit(x, y, g); } } } kk=0; stop(); } public void actionPerformed(ActionEvent e) { // Button String tst; tst=e.getActionCommand(); if (bs.equals(tst)) { kk=1; } start(); } }