// Gauss random noise,  Evgeny Demidov, 12 Feb 2002
import java.awt.*;
import java.awt.event.*;
public class Gauss extends java.applet.Applet
 implements ItemListener, ActionListener{
  int  n = 300, n1 = n-1, Rc = 32, Lc, w, h, h2, h0, lbSize = 30;
  double p[], p1[], G[];
  Choice chRc;    Label lbRc;    Button btNew;

public void init() {
  w = getSize().width;
  h = getSize().height - lbSize;  h2 = h/2; h0 = h2 + lbSize;
  p = new double[n];     p1 = new double[n];
  G = new double[128];
  for (int i = 0; i < n; i++) p[i] = 2*Math.random() - 1;
//  p[150] = -7;
  String s=getParameter("Rc"); if (s != null) Rc = Integer.parseInt(s);
  Lc = 2*Rc;
  double Rc2 = Rc*Rc, sqr = Math.sqrt(Rc);
  for (int i = 0; i < Lc; i++) G[i] = Math.exp(-(i*i/Rc2))/sqr;
  lbRc = new Label("Rc", Label.RIGHT);  add(lbRc);
  chRc = new Choice();
  for (int i = 0, r = 1; i < 7; i++){
    chRc.addItem(Integer.toString(r));  r *= 2;}
  chRc.select("" + Rc);  chRc.addItemListener(this);  add(chRc);
  btNew = new Button("New");   btNew.addActionListener(this);
  add(btNew);
  averaging();
}
public void averaging(){
  for (int i = Lc; i < n-Lc; i++){
    double sum = G[0]*p[i];
    for (int j = 1; j < Lc; j++) sum += G[j]*(p[i+j]+p[i-j]);
    p1[i] = .3*sum;}
}

public void paint(Graphics g) {
  g.setColor(Color.white);   g.fillRect(0, 0, w, h+lbSize);
  g.setColor(Color.black);   g.drawLine(0,h0 ,w,h0);
  int x = 0, x0 = 0, y, y0 = (int)(h2*p[0]) + h0;
  g.setColor(new Color(200,200,255));
  for (int i = 1; i < n; i++){
    x += 2;  y = (int)(h2*p[i]) + h0;
    g.drawLine(x0,y0 ,x,y);
    x0 = x;  y0 = y;}
  g.setColor(Color.red);
  x = x0 = 2*Lc;  y0 = (int)(h2*p1[Lc]) + h0;
  for (int i = Lc+1; i < n-Lc; i++){
    x += 2;  y = (int)(h2*p1[i]) + h0;
    g.drawLine(x0,y0 ,x,y);
    x0 = x;  y0 = y;}
}

public void itemStateChanged(ItemEvent e){
  Rc = Integer.parseInt(chRc.getSelectedItem());
  Lc = 2*Rc;
  double Rc2 = Rc*Rc, sqr = Math.sqrt(Rc);
  for (int i = 0; i < Lc; i++) G[i] = Math.exp(-(i*i/Rc2))/sqr;
  averaging();
  repaint();
}
public void actionPerformed(ActionEvent e){
  for (int i = 0; i < n; i++) p[i] = 2*Math.random() - 1;
  averaging();
  repaint();
}
public void update(Graphics g){ paint(g); }
}
