// lorenz_attractor.java  example of chaos
//    dx/dt = sigma*(y-x)
//    dy/dt = x*(rho-z)-y
//    dz/dt = x*y-beta*z
//    for sigma=10, rho=28, beta=8/3  
//    at t=0  x=0, y=1, z=0
//    use small detla t and plot 3D x,y,z
//
//    x_next = x + delta_t*dxdt
//    y_next = y + delta_t*dydt
//    z_next = z + delta_t*dzdt
//    t = t+delta_t    x = x_next    y = y_next    z = z_next
//    iterate

import java.awt.*;
import java.awt.event.*;

public class lorentz_attractor extends Frame
{
  double t = 0.0;
  double delta_t = 1.0e-3;
  double x = 0.0;
  double x_next = 0.0;
  double x_min = 99.0;
  double x_max = -99.0;
  double y = 1.0;
  double y_next = 0.0;
  double y_min = 99.0;
  double y_max = -99.0;
  double z = 0.0;
  double z_next = 0.0;
  double z_min = 99.0;
  double z_max = -99.0;
  double sigma = 10.0;
  double rho = 28.0;
  double beta = 8.0/3.0;
  int width = 600;
  int height = 600;
  int cmin = 10;
  int rd = 255;
  int gr = cmin;
  int bl = cmin;

  lorentz_attractor()
  {
    setTitle("lorentz_attractor");
    setSize(width, height);
    setBackground(Color.white);
    setForeground(Color.black);
    addWindowListener(new WindowAdapter()
    {
      public void windowClosing(WindowEvent e)
      {
        System.exit(0);
      }
    });
    setVisible(true);
    this.addMouseListener (new mousePressHandler());
  } // end lorentz_attractor constructor

  class mousePressHandler extends MouseAdapter
  {
    public void mousePressed (MouseEvent e)
    {
      requestFocus();
      repaint();
    }
  } // end mousePressHandler

  public void paint(Graphics g)
  {
    int xp, yp, xp1, yp1;
    int xoff = 40;
    int yoff = 140;
    double dxdt, dydt, dzdt;

    System.out.println("lorentz_attractor.java running");
    g.setColor(Color.black);
    g.drawString("lorentz_attractor   click to draw next million points",
                 10, height-10);
    g.drawLine(15, height-30, 35, height-30);
    g.drawString("X", 40, height-25);
    g.drawLine(15, height-30, 15, height-50);
    g.drawString("Y", 10, height-55);
    g.drawLine(15, height-30, 35, height-50);
    g.drawString("Z", 40, height-55);

    for(int i=0; i<1.0e6; i++)
    {
      dxdt = sigma*(y-x);
      dydt = x*(rho-z)-y;
      dzdt = x*y-beta*z;
      x_next = x + delta_t*dxdt;
      y_next = y + delta_t*dydt;
      z_next = z + delta_t*dzdt;
      x_max = Math.max(x_max, x);
      x_min = Math.min(x_min, x);
      y_max = Math.max(y_max, y);
      y_min = Math.min(y_min, y);
      z_max = Math.max(z_max, z);
      z_min = Math.min(z_min, z);

      if(rd > cmin && bl == cmin)
      {
        rd--;
        gr++;
      }
      else if(gr > cmin && rd == cmin)
      {
        gr--;
        bl++;
      }
      else if(bl > cmin && gr == cmin)
      {
	  bl--;
	  rd++;
      }
      g.setColor(new Color(rd, gr, bl));
      xp = xoff + (int)(10.0*(x+0.7071*z));
      yp = yoff + (int)(7.0*(y+0.7071*z));
      xp1 = xoff + (int)(10.0*(x_next+0.7071*z_next));
      yp1 = yoff + (int)(7.0*(y_next+0.7071*z_next));
      g.drawLine(xp, yp, xp1, yp1);
      /* g.drawOval(xp, yp, 2, 2); */
      t = t+delta_t;
      x = x_next;
      y = y_next;
      z = z_next;
    }
    System.out.println("xmin="+x_min);
    System.out.println("xmax="+x_max);
    System.out.println("ymin="+y_min);
    System.out.println("ymax="+y_max);
    System.out.println("zmin="+z_min);
    System.out.println("zmax="+z_max);
    g.setColor(Color.black);
    g.drawString("Xmin="+Double.toString(x_min)+", Xmax="+Double.toString(x_max),
                 60, height-25);
    g.drawString("Ymin="+Double.toString(y_min)+", Ymax="+Double.toString(y_max),
                 60, height-40);
    g.drawString("Zmin="+Double.toString(z_min)+", Zmax="+Double.toString(z_max),
                 60, height-55);
    System.out.println("lorentz_attractor.java finished");
  } // end paint

  public static void main(String args[])
  {
    new lorentz_attractor();
  } // end main
} // end class lorentz_attractor


