// 2D Quadratic map with Orbits, Evgeny Demidov, 7 Sep 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 { int w,h,w2,h2, it=3000, rand=50; double Xo=3, Yo=-4, K=.3, Pi2 = Math.PI*2, Xc=Math.PI, Yc=0, dX=Pi2, Mx, My; Image buffImage; Graphics buffGraphics; boolean bClear = true; Label lbK, lbIt; TextField tfK, tfXY, tfIt, tfRand; Button btClear, btRand; public void init() { double dx = Pi2, dy = 4.; w = getSize().width; h = getSize().height; w2 = w/2; h2 = h/2; buffImage = createImage(w, h); buffGraphics = buffImage.getGraphics(); // buffGraphics.setFont( // new Font( buffGraphics.getFont().getName(), Font.BOLD, 15 ) ); String s=getParameter("K"); if (s != null) K = Double.valueOf(s).doubleValue(); s=getParameter("it"); if (s != null) it = Integer.parseInt(s); s=getParameter("rand"); if (s != null) rand = Integer.parseInt(s); s=getParameter("coord"); if (s != null){ StringTokenizer st = new StringTokenizer(s); Xc = Double.valueOf(st.nextToken()).doubleValue(); Yc = Double.valueOf(st.nextToken()).doubleValue(); dx = Double.valueOf(st.nextToken()).doubleValue(); dy = Double.valueOf(st.nextToken()).doubleValue();} Mx = dx/w; My = dy/h; this.setLayout( new FlowLayout(FlowLayout.LEFT, 0, 0) ); tfXY = new TextField( ""+(float)Xc+" "+(float)Yc+"; "+(float)dx+ " "+(float)dy, 30); add(tfXY); lbK = new Label("K", Label.RIGHT); add(lbK); tfK = new TextField( "" + K, 5); add(tfK); tfK.addKeyListener(this); lbIt = new Label("it", Label.RIGHT); add(lbIt); tfIt = new TextField( "" + it, 5); add(tfIt); tfK.addKeyListener(this); btClear = new Button("Clear"); btClear.addActionListener(this); add(btClear); btRand = new Button("Rand"); btRand.addActionListener(this); add(btRand); tfRand = new TextField( "" + rand, 3); add(tfRand); tfRand.addKeyListener(this); addMouseListener(this); clear(); random(); } public void destroy() { removeMouseListener(this); } public void random(){ buffGraphics.setColor(Color.blue); for(int i = 0; i < rand; i++){ Xo = Xc + Mx*w*(Math.random() - .5); Yo = Yc + My*h*(Math.random() - .5); iterate();} } public void iterate() { double X=Xo, Y; for(int i = 0; i < it; i++){ Y = X; X = 2.*(K - X*X) - Yo; int ix = w2 + (int)((X-Xc)/Mx), iy = h2 - (int)((Y-Yc)/My); buffGraphics.drawLine( ix,iy, ix,iy); Yo = Y;} repaint(); } public void Orbits(int kit) { buffGraphics.setColor(Color.red); double X=Xo, Y; int ix, iy, ix0 = w2 + (int)((Xo-Xc)/Mx), iy0 = h2 - (int)((Yo-Yc)/My); for(int i = 0; i < kit; i++){ Y = X; X = 2.*(K - X*X) - Yo; ix = w2 + (int)((X-Xc)/Mx); iy = h2 - (int)((Y-Yc)/My); buffGraphics.drawLine( ix0,iy0, ix,iy); buffGraphics.fillRect( ix0, iy0, 3, 3); ix0 = ix; iy0 = iy; Yo = Y;} // repaint(); } public void mouseClicked(MouseEvent e){} // event handling public void mousePressed(MouseEvent e) { int mx0 = e.getX() - w2, my0 = h2 - e.getY(); Xo = mx0*Mx + Xc; Yo = my0*My + Yc; if ( e.isAltDown() ){ Xc = Xo; Yc = Yo; My /= 2.; if ( !e.isShiftDown() ) Mx /= 2.; tfXY.setText(""+(float)Xc+" "+(float)Yc+"; "+(float)(w*Mx)+ " "+(float)(h*My) ); clear(); random(); return;} if ( e.isControlDown() ){ Xc = Xo; Yc = Yo; My *= 2.; if ( !e.isShiftDown() ) Mx *= 2.; tfXY.setText(""+(float)Xc+" "+(float)Yc+"; "+(float)(w*Mx)+ " "+(float)(h*My) ); clear(); random(); return;} if ( e.isShiftDown() ){ Orbits(1); repaint();} else{ showStatus("X=" + (float)Xo + " Y=" + (float)Yo ); buffGraphics.setColor(Color.black); iterate();} } 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") ){ clear(); repaint();} else random(); } public void keyTyped(KeyEvent e) {} public void keyPressed(KeyEvent e) {} public void keyReleased(KeyEvent e) { final int keyEnter = 10; if (e.getKeyCode() == keyEnter) { try{ double Ko = K; K = Double.valueOf(tfK.getText()).doubleValue(); it = Integer.parseInt(tfIt.getText()); rand = Integer.parseInt(tfRand.getText()); if (Ko != K){ clear(); random();} }catch ( NumberFormatException ne) {} } e.consume(); } public void clear(){ buffGraphics.setColor(Color.white); buffGraphics.fillRect(0, 0, w, h); } public void paint(Graphics g) { drawLabel(); g.drawImage(buffImage, 0, 0, this); } public void drawLabel() { int max=0; double dw2 = w2, dh2 = h2; while (true) { String s = getParameter("or"+max); if (s == null) break; StringTokenizer st = new StringTokenizer(s); Xo = Double.valueOf(st.nextToken()).doubleValue(); Yo = Double.valueOf(st.nextToken()).doubleValue(); Orbits( Integer.parseInt(st.nextToken()) ); max++; } max = 0; buffGraphics.setColor(Color.black); while (true) { String s=getParameter("lb"+max); if (s == null) break; StringTokenizer st = new StringTokenizer(s); double x=w2+(Double.valueOf(st.nextToken()).doubleValue()-Xc)/Mx, y=h2-(Double.valueOf(st.nextToken()).doubleValue()-Yc)/My; if ( (x0)&&(y0) ) buffGraphics.drawString(st.nextToken(), (int)x, (int)y); max++; } } public void update(Graphics g){ paint(g); } }