// Helium Periodic Orbits, Evgeny Demidov, 2 Apr 2003 import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.util.StringTokenizer; public class @file extends java.applet.Applet implements MouseListener, KeyListener, ActionListener, Runnable { Thread thIntegrate; int w,h,w2,h2,w4, delay=0, Mx=100, My=25, x1,x2,y1,y2; double Q1_0= .6, P1_0=0, Q2_0= .5, P2_0=0, Q1_1, P1_1, Q2_1, P2_1, Q12,Q22, E, ds=.001, ds2, ds8,t; Image buffImage; Graphics buffGraphics; boolean bRun = false, bClear = true; Label lbDs, lbDelay; TextField tfDs, tfDelay; Button btRun, btClear; public void init() { w = getSize().width; h = getSize().height; w2 = w/2; h2 = h/2; w4 = w/4; buffImage = createImage(w, h); buffGraphics = buffImage.getGraphics(); String s=getParameter("Delay"); if (s != null) delay = Integer.parseInt(s); s=getParameter("coord"); if (s != null){ StringTokenizer st = new StringTokenizer(s); Q1_0 = Double.valueOf(st.nextToken()).doubleValue(); P1_0 = Double.valueOf(st.nextToken()).doubleValue(); Q2_0 = Double.valueOf(st.nextToken()).doubleValue(); P2_0 = Double.valueOf(st.nextToken()).doubleValue();} Q2_0 = Q1_0; E = -1; P1_0 = Math.sqrt(14 - 4*Q1_0*Q1_0); P2_0 = -P1_0; Q1_1 = Q1_0; P1_1 = P1_0; Q2_1 = Q2_0; P2_1 = P2_0; Q12 = Q1_1*Q1_1; Q22 = Q2_1*Q2_1; // E = ((P1_1*P1_1 - 16.)/Q12 + (P2_1*P2_1 - 16.)/Q22)/8. + 1/(Q12 + Q22); ds2 = ds*2; ds8 = ds/8; x1 = (int)(Mx*Q1_1); y1 = (int)(My*P1_1); x2 = (int)(Mx*Q2_1); y2 = -(int)(My*P2_1); lbDs = new Label("ds", Label.RIGHT); add(lbDs); tfDs = new TextField( "" + ds, 3); add(tfDs); lbDelay = new Label("Delay", Label.RIGHT); add(lbDelay); tfDelay = new TextField( "" + delay, 4); add(tfDelay); tfDs.addKeyListener(this); tfDelay.addKeyListener(this); btRun = new Button("Run "); btRun.addActionListener(this); add(btRun); btClear = new Button("Clear"); btClear.addActionListener(this); add(btClear); addMouseListener(this); } public void destroy() { removeMouseListener(this); } public void run() { double Q1_12, Q2_12, R12; while(true) { if ( Thread.currentThread() != thIntegrate ) return; for (int i=0; i < 3; i++){ Q1_0 = Q1_1; Q2_0 = Q2_1; P1_0 = P1_1; P2_0 = P2_1; Q1_12 = Q1_0 + P1_0*Q22*ds8; Q2_12 = Q2_0 + P2_0*Q12*ds8; Q12 = Q1_12*Q1_12; Q22 = Q2_12*Q2_12; R12 = Q12 + Q22; R12 *= R12; P1_1 = P1_0 + Q1_12*(2. - P2_0*P2_0/8. + Q22*(E - Q22/R12))*ds2; P2_1 = P2_0 + Q2_12*(2. - P1_0*P1_0/8. + Q12*(E - Q12/R12))*ds2; Q1_1 = Q1_12 + P1_1*Q22*ds8; Q2_1 = Q2_12 + P2_1*Q12*ds8; Q12 = Q1_1*Q1_1; Q22 = Q2_1*Q2_1; t += ds; } E = ((P1_1*P1_1 - 16.)/Q12 + (P2_1*P2_1 - 16.)/Q22)/8. + 1/(Q12 + Q22); repaint(); try { Thread.sleep( delay ); } catch (InterruptedException e) {} } } public void stop() { thIntegrate = null; } public void mouseClicked(MouseEvent e){} // event handling public void mousePressed(MouseEvent e) { int mx0 = e.getX() - w4, my0 = h2 - e.getY(); if (mx0 > 0){ Q1_1 = Q1_0 = 2*(double)mx0/Mx; P1_1 = P1_0 = (double)my0/My; x1 = (int)(Mx*Q1_1); y1 = (int)(My*P1_1); Q12 = Q1_1*Q1_1;} else{ Q2_1 = Q2_0 =-2*(double)mx0/Mx; P2_1 = P2_0 =-(double)my0/My; x2 = (int)(Mx*Q2_1); y2 = -(int)(My*P2_1); Q22 = Q2_1*Q2_1;} E = ((P1_1*P1_1 - 16.)/Q12 + (P2_1*P2_1 - 16.)/Q22)/8. + 1/(Q12 + Q22); repaint(); } public void mouseReleased(MouseEvent e){} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void actionPerformed(ActionEvent e){ if ( e.getActionCommand().equals("Clear") ) { bClear = true; repaint();} else{ if (bRun) { bRun = false; btRun.setLabel("Run "); thIntegrate = null;} else { bRun = true; btRun.setLabel("Stop"); thIntegrate = new Thread(this); thIntegrate.start();} } } public void keyTyped(KeyEvent e) {} public void keyPressed(KeyEvent e) {} public void keyReleased(KeyEvent e) { final int keyEnter = 10; if (e.getKeyCode() == keyEnter) { try{ ds = Double.valueOf(tfDs.getText()).doubleValue(); ds2 = ds*2; ds8 = ds/8; delay = Integer.parseInt( tfDelay.getText() ); }catch ( NumberFormatException ne) {} } e.consume(); } public void paint(Graphics g) { if (bClear){ buffGraphics.setColor(Color.white); buffGraphics.fillRect(0, 0, w, h); buffGraphics.setColor(Color.lightGray); buffGraphics.drawLine(w4,0,w4,h); buffGraphics.drawLine(0,h2,w2,h2); buffGraphics.drawLine(w2,h,w,h-w2); bClear = false;} buffGraphics.setColor(Color.blue); int x,y, xx; x = (int)(Mx*Math.abs(Q1_1)); y = (int)(My*P1_1); if (Q1_1 < 0.) y = -y; buffGraphics.drawLine( w4+(x1>>1),h2-y1, w4+(x>>1),h2-y); y1 = y; buffGraphics.setColor(Color.red); xx = (int)(Mx*Math.abs(Q2_1)); y = (int)(My*P2_1); if (Q2_1 > 0.) y = -y; buffGraphics.drawLine( w4-(x2>>1),h2-y2, w4-(xx>>1),h2-y); buffGraphics.setColor(Color.black); buffGraphics.drawLine( w2+x1,h-x2, w2+x,h-xx); x1 = x; x2 = xx; y2 = y; g.drawImage(buffImage, 0, 0, this); showStatus("E="+(float)E+" s="+(float)t ); } public void update(Graphics g){ paint(g); } }